在测试函数中有个函数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;