本帖最后由 robe.zhang 于 2021-6-29 23:40 编辑
【ALINX AXU2CGB试用】IIC设备文件驱动源码分析
这个是 IIC 设备文件有关的驱动源码:也是模块的形式,初始化的 i2c_dev_init 函数 第 722 行:注册字符设备号 第 726 行:创建类,存在 i2c-dev类 第734行,向 IIC 总线注册通知链,通知链主要响应两个通知,add 添加 IICdev 设备,del删除IICdev设备,分别是两个函数完成对应的动作i2cdev_attach_adapter函数,i2cdev_detach_adapter 函数 第739行,遍历IIC总线的每一个设备,调用i2cdev_attach_adapter 注册 i2c_dev 设备文件
i2cdev_attach_adapter 函数: 第 652 行,添加设备文件,名字是i2c-%d,%d 在c语言是整数,主设备号是89 Linux 系统中对应的设备文件:
第 645 行:是对应设备文件的ops 接口: 先看 open函数:在 adapter下创建 client,并设置 client 为 file->private_data,几乎就是标准的 open 方法,是不是很熟悉 Release 函数:和 open 是相反的操作,释放 client,file->private_data 置为空 Read 函数:调用 i2c_master_recv接受数据,调用 copy_to_user 把接收的数据复制到用户空间。因为驱动工作在内核空间,驱动接受到的数据也在内核空间,所以接收到的数据需要复制到用户空间,应用层的 app 才能使用,需要用到 copy_to_user 函数 追踪一下 i2c_master_recv 函数:调用了 i2c_transfer_buffer_flags 函数 进一层调用了i2c_transfer_buffer_flags 函数,i2c_transfer_buffer_flags 函数准备了一个 msg 消息,flags 来自上一层函数的 I2C_M_RD 标记,读取消息。准备好 msg 消息后调用 i2c_transfer 函数发送消息 i2c_transfer 函数调用 __i2c_transfer函数 __i2c_transfer 函数 调用了 adap->algo->master_xfer(adap, msgs, num); 函数 回到另一篇文章 I2C 适配器驱动中的部分,如下箭头位置, adap->algo->master_xfer 函数在 I2C 适配器驱动中实现的,是通过读写寄存器,完成 IIC 数据传递的。因为是 msg 消息标识 RD 读,所以这是个 读数据的消息,对应文件操作的 read 函数。整个文件系统read 读取消息过程分析完了。 cdns_i2c_algo 是在 I2C适配器驱动中实现的,上一篇文章分析过了,不赘述。这里其实跨越了好几层,文件系统操作层面的东西,跨越到了驱动层。驱动层实现了,文件系统只管用就完事。层次分明,各司其职。 Write 函数,调用了 i2c_master_send函数 i2c_master_send 函数调用了 i2c_transfer_buffer_flags 函数,和i2c_master_recv函数中是完全一样,唯一区别是msg 的 flags 不再是 RD而是WR / 0,仅此。最终也是调用驱动层实现的 adap->algo->master_xfer 函数完成数据传送。 Seek 函数:返回一个错误,显示非法seek,IIC不支持seek unlocked_ioctl 函数:不同的 case,通过设置 flags,或者复制内核空间数据到用户空间,或者i2c 收发数据,或者smbus 协议传输数据,等。完成 ioctl 功能 compat_ioctl 函数:和 unlocked_ioctl函数的实现差不多。 i2cdev_detach_adapter 函数,和 attach 相反,删除字符设备,销毁设备文件 IIC 设备文件相关的源码分析到此为止。
开发板有两个 iic 适配器,所以能找到两个设备文件,分别是 0,1
|