应用层对i2c通用驱动接口与eeprom的i2c驱动接口从应用层到内核层调用区别和联系

本文详细介绍了应用层通过i2c通用驱动接口操作I2C设备的过程,包括open、ioctl、write等步骤,并分析了i2c_master_send函数在数据传输中的作用。同时,对比了针对EEPROM设备的特定接口,如at24_driver,探讨其二进制读写接口的不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:

i2c通用接口调用过程:

i2c_dev_init--》register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops) //I2c-dev.c (drivers\i2c)

static const struct file_operations i2cdev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = i2cdev_read,
.write = i2cdev_write,
.unlocked_ioctl = i2cdev_ioctl,
.open = i2cdev_open,
.release = i2cdev_release,

};

对一个设备操作过程如下:

应用层调用write()函数后首先进入的是i2c类设备的write函数,即i2cdev_fops中的write方法。

此处的i2cdev_fops对应的是系统中所有i2c类设备的操作。也就是说系统中所有i2c adapter read()

write() open() close() ioctl()等操作,首先调用的是i2ci2cdev_fops中的方法,通过i2c类中的方法

再去寻找adapter 对应的算法i2c_algorithm,此处s3c2440对应的为s3c24xx_i2c_algorithm

i2c的操作方法

1.首先open

2.ioctl设置at24c02的地址

3.write()

1.open设备/dev/i2c-0

open通过系统调用最后调用到fopsi2cdev_open函数。


static int i2cdev_open(struct inode *inode, struct file *file)  

{  

    。。。 。。。  

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

    if (!adap)  

        return -ENODEV;  

  

    。。。 。。。  

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

10     if (!client) {  

11         i2c_put_adapter(adap);  

12         return -ENOMEM;  

13     }  

14     snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);  

15     client->driver = &i2cdev_driver;  

16   

17     client->adapter = adap;  

18     file->private_data = client;  

19   

20     return 0;  

21 }  

可以发现此函数的作用是根据/dev/i2c-0的设备号找到对应的adapter,然后将其保存到新建的client中。

需要注意的是,此处的client与驱动中的client不同,这里的client并不会注册到总线上,和i2c驱动模型的代码无关。

此处的client只是用来保存client地址信息等。

最后将这个clietn保存到file->private_data中,供ioctl() write() open()等操作使用。

2. ioctl

应用层调用ioctl后会调用到i2cdev_ioctl()函数,此处使用的是I2C_SLAVE_FORCE,用于设置at24c02的地址。

3.write

write通过系统调用最后执行fops这中的i2cdev_write函数

[cpp] view plain

22 static ssize_t i2cdev_write(struct file *file, const char __user *buf,  

23         size_t count, loff_t *offset)  

24 {  

25     。。。 。。。  

26     struct i2c_client *client = file->private_data;  

27         。。。 。。。  

28     tmp = memdup_user(buf, count);  

29     。。。 。。。  

30     ret = i2c_master_send(client, tmp, count);  

31     。。。 。。。  

32 }  


可以发现,在write函数中首先做的就是将在open操作中保存到file>private_data中的client取出然后通过memdup_user函数将用户空间的缓冲区拷贝到内核空间。最后调用函数i2c_master_send()

[cpp] view plain

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值