MINI2440i2c驱动学习二

来源:互联网 发布:网络真人视频赌博揭秘 编辑:程序博客网 时间:2024/05/18 04:01
 

在测试函数中有个函数eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e);其中里面的调用如下

int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom* e)
{
 int funcs, fd, r;
 e->fd = e->addr = 0;
 e->dev = 0;
 
 fd = open(dev_fqn, O_RDWR);
 if(fd <= 0)
 {
  fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));
  return -1;
 }

 // get funcs list
 if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0))
 {
  fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));
  return -1;
 }

当程序执行到fd = open(dev_fqn, O_RDWR);时就会调用驱动中的i2cdev_open(struct inode *inode, struct file *file)函数

static int i2cdev_open(struct inode *inode, struct file *file)
{
 unsigned int minor = iminor(inode);
 struct i2c_client *client;
 struct i2c_adapter *adap;
 struct i2c_dev *i2c_dev;
 int ret = 0;

 lock_kernel();
 i2c_dev = i2c_dev_get_by_minor(minor);
 if (!i2c_dev) {
  ret = -ENODEV;
  goto out;
 }

 adap = i2c_get_adapter(i2c_dev->adap->nr);
 if (!adap) {
  ret = -ENODEV;
  goto out;
 }

 
 client = kzalloc(sizeof(*client), GFP_KERNEL);
 if (!client) {
  i2c_put_adapter(adap);
  ret = -ENOMEM;
  goto out;
 }
 snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
 client->driver = &i2cdev_driver;

 client->adapter = adap;
 file->private_data = client;

out:
 unlock_kernel();
 return ret;
}
驱动做了些什么呢??

慢慢分析:

unsigned int minor = iminor(inode);

获得被打开的设备文件的次设备号,通过函数static inline unsigned iminor(const struct inode *inode)
{
 return MINOR(inode->i_rdev);
}

i2c_dev = i2c_dev_get_by_minor(minor);

adap = i2c_get_adapter(i2c_dev->adap->nr);

获得i2c_dev和adap结构体主要是为了后面的client

client = kzalloc(sizeof(*client), GFP_KERNEL);

 client->driver = &i2cdev_driver;

 client->adapter = adap;

填充client.一个client结构体就表示一个i2c设备

file->private_data = client;

是为了在以后的操作中能通过file中的private_data获得client

同理,释放函数就是和open函数相反,在条用close()是static int i2cdev_release(struct inode *inode, struct file *file)
{
 struct i2c_client *client = file->private_data;

 i2c_put_adapter(client->adapter);
 kfree(client);
 file->private_data = NULL;

 return 0;
}被调用,在这里释放了client结构体和file->private_data = NULL;

原创粉丝点击