IIC (三) -- I2C系统驱动程序模型

回顾字符设备驱动程序

在这里插入图片描述

编写字符设备驱动程序的步骤
  1. 确定主设备号
  2. 创建file_operations结构体
    • 在里面填充drv_open/drv_read/drv_ioctl等函数
  3. 注册file_operations结构体
    • register_chrdev(major, &fops, name)
    • cdev_init
  4. 创建入口函数调用
  5. 以及出口函数
    • 在出口函数unregister_chrdev
  6. 辅助函数(帮助系统自动创建设备节点)
    • class_create
    • device_create
I2C驱动程序的层次

在这里插入图片描述
I2C Core就是I2C核心层,它的作用:

  • 提供统一的访问函数,比如i2c_transfer、i2c_smbus_xfer等
  • 实现I2C总线-设备-驱动模型,管理:I2C设备(i2c_client)、I2C设备驱动(i2c_driver)、I2C控制器(i2c_adapter)
I2C总线-设备-驱动模型

在这里插入图片描述

根据 总线-设备-驱动模型,分为三部分,与设备相关联的i2c_client需要绑定硬件相关的信息。与driver相关的功能由i2c_driver提供。通过i2c_bus_type中i2c_device_match函数,依次比较设备树,id_table将两者绑定起来,若比较成功,接着调用i2c_device_probe函数进行注册。

i2c_driver

在这里插入图片描述

i2c_driver表明能支持哪些设备:

  • 使用of_match_table来判断
    • 设备树中,某个I2C控制器节点下可以创建I2C设备的节点
      • 如果I2C设备节点的compatible属性跟of_match_table的某项兼容,则匹配成功
    • i2c_client.name跟某个of_match_table[i].compatible值相同,则匹配成功
  • 使用id_table来判断
    • i2c_client.name跟某个id_table[i].name值相同,则匹配成功

i2c_driver跟i2c_client匹配成功后,就调用i2c_driver.probe函数。

i2c_client

i2c_client表示一个I2C设备,创建i2c_client的方法有4种:
1.通过设备树来创建。
以at24c02为例,通过compatible属性来匹配创建:
在这里插入图片描述
2.有时候无法知道该设备挂载哪个I2C bus下,无法知道它对应的I2C bus number。
但是可以通过其他方法知道对应的i2c_adapter结构体。
可以使用下面两个函数来创建i2c_client:

  • i2c_new_device
    • 会创建i2c_client,即使该设备并不存在
  • i2c_new_probed_device
    • 它成功的话,会创建i2c_client,并且表示这个设备肯定存在
      在这里插入图片描述
      需要同时提供adapter和board_info信息。
      “tda18211”为需要和后续的device_id中的字符串匹配的名称,如果匹配才会调用probe函数。0x60为从设备地址。

在这里插入图片描述
在这里插入图片描述

3.由i2c_driver.detect函数来判断是否有对应的I2C设备并生成i2c_client
4.通过用户空间(user-space)生成
调试时、或者不方便通过代码明确地生成i2c_client时,可以通过用户空间来生成。

  // 创建一个i2c_client, .name = "eeprom", .addr=0x50, .adapter是i2c-3
  # echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device
  
  // 删除一个i2c_client
  # echo 0x50 > /sys/bus/i2c/devices/i2c-3/delete_device
i2c驱动的注册过程

整体的层次关系从应用层设备层核心层adapter层实际硬件可以参考I2C驱动程序的层次,而函数之间的调用关系为i2c_register_driver->driver_register(&driver->driver)->driver_find。
所以这里主要介绍一下这几个重要函数的作用。

Reference:D:\ubuntu iso\100ask\Linux-4.9.88\drivers\iio\dac\ad5064.c

i2c_register_driver

在这里插入图片描述

ad5064_i2c_driver

在这里插入图片描述
name:支持哪些设备,主要判断设备树中的I2C设备
probe:找到能支持的设备后,该函数被调用。

  • probe函数中,分配/注册/设置 file_operation结构体
  • file_operation中,使用i2c_transfer等函数发起I2C传输。

id_table:能支持哪些设备

i2c_transfer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
client:I2C的从设备句柄
buf:向从设备写的数据
count:传输的字节数
在这里插入图片描述
i2c_transfer实际调用的是adapter下面实现的master_xfer函数,

i2c_device_id

在这里插入图片描述

driver_register

i2c_register_driver会调用driver_register将设备驱动添加到总线的设备驱动链表中,在此之前,会初始化一个clients的链表,用来存放具体I2C设备信息。
在这里插入图片描述
在driver_register中,通过driver_find来判断驱动是否已经注册,然后会调用bus_add_driver将设备驱动添加到总线上。
kobject_uevent函数发送KOBJ_ADD / KOBJ_REMOVE等事件,udev会调用mknod函数,在用户空间创建/dev/XXX文件节点。这里的操作可以代替我们手动调用class_create和device_create创建设备节点。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值