最后更新:2022-07-05 02:35:44 手机定位技术交流文章
参考博客:I2C通信协议细节和通信过程分析;
参考博客: 通过KXTF9-2050芯片分析I2C协议;

(一)I2C子系统分为三个层:I2C核心层、I2C适配驱动器和I2C设备驱动器;
(2)I2C核心层:管理I2C驱动器和I2C设备的注册和匹配,实现I2C通信方法,是I2C通信的抽象框架,与特定硬件无关;
(三)I2C适配器驱动器:与SOC相对应的I2C控制器,将I2C控制器视为设备,实现I2C控制器的驱动程序代码,以及与SOC有关的特定程序;
(4)I2C设备驱动程序:每个外部设备都有与特定I2C接口相关的特殊I2C驱动程序代码;
(1)内核首先在启动时注册I2C核心层,包括注册I2C总线,提供适配器驱动和设备驱动的注册和卸载接口;
(二)内核将注册的I2C适配器驱动到I2C核心层;
(三)内核驱动已注册的I2C设备进入I2C核心层;
(4)I2C适配器驱动器和I2C设备驱动器在I2C总线上匹配,如果匹配,则调用I2C设备驱动器探测方法;
(5)I2C适配器驱动器与I2C设备驱动器匹配的影响:I2C设备驱动器调用I2C适配器驱动器在I2C总线上实现主控SoC与外部I2C接口之间的通信,I2C适配器驱动器只提供最基本的数据传输功能,具体通信协议由I2C驱动的设备控制;
参考博客:I2C驱动实现两个想法(i2c -dev.c和i2c-core.(c));
| 变量名 | 解释 |
|---|---|
| id | 适配器ID包括/linux/i2c - 某些特定适配器的ID.h定义其ID。 这个字段在普通适配器驱动器中不常见 |
| class | 检查某些I2C设备驱动程序中的成员的适配器类型,以确定该设备是否由适配器操作 |
| algo | 指针描述组件的通信方法结构,是适配器I2C控制器的特定操作功能 |
| algo_data | 指向通信方法数据,成员不会被I2C核心层修改,只用于特定i2c_algorithm使用 |
| timeout | 传输超时时间 |
| retries | 传输超时的重试次数 |
| name | 通过 sys/bus/i2c/devices/i2c-x/name访问的适配器名称(x=0,1,2.. ) |
| nr | 设备节点/dev/i2c-x中的x(x=0,1,2..)的总线代码(同样的适配器代码) |
| 适配器能力的宏定义 | 解释 |
|---|---|
| I2C_FUNC_I2C | 支持I2C通信 |
| I2C_FUNC_SMBUS_EMUL | 支持SMBus协议仿真 |
| I2C_FUNC_PROTOCOL_MANGLING | 支持I2C协议修改,即支持非标准序列访问设备 |
| I2C_FUNC_10BIT_ADDR | 支持数据传输的10位模式,通常是8位模式 |
| 变量名 | 解释 |
|---|---|
| master_xfer | 指向特定I2C传输功能的指示器,相应的传输通常通过适配器硬件的直接操作启动。 这些功能由:使用传输方法的适配器,等待传输的消息 msgs,以及消息数 返回值:返回成功发送的邮件数目,未能返回负值 |
| smbus_xfer | 指向特定SMBus传输功能 |
| functionality | 指向返回适配器支持函数的功能,以查看适配能力。 这些函数在 include/linux/i2c中定义的宏定义方式中表达 |
(一)SMBus协议主要基于I2C总线规范,并基于I2C扩展,但访问序列也有一些差异;
(2)如果I2C协议支持,则执行 master_xfer函数指针,如果SMBus协议支持,则执行 thembus_xfer函数指针;
| 变量名 | 解释 |
|---|---|
| attach_adapter | 与i2c_adapter连接的函数指针:(1)在将i2c_driver添加到系统时,驱动注册函数通过所有适配器类i2c_adapter_class的设备,将attache_adapter方法应用到驱动器上。 (2)因此,在添加i2c_adapter时,适配器登记函数通过所有驱动器的总线i2c_bus_type。如果定义了attache_adapter方法,它也将被调用 |
| detach_adapter | 功能指针关闭i2c_adapter |
| probe | 当设备在总线i2c_bus_type与设备驱动器相匹配时被调用 |
| driver | 在注册i2c_driver对象时,i2c_driver->driver的总线类型被指定为i2c_bus_type |
| id_table | 保存由驱动器支持的设备列表,当驱动器匹配设备时将使用此列表 |
| detect | 基于设备检测机制的12C设备驱动:设备检测调制功能 |
| address_list | 设备探测的地址范围 |
| clients | 探测到的设备列表 |
| 变量名 | 解释 |
|---|---|
| flags | I2C_CLIENT_TEN:设备使用10bit地址; I2C_CLIENT_PEC:SMBus包设备错误检查 |
| addr | 设备地址,在7位地址格式中,存储在会员的下位7位 |
| name | 设备的名称 |
| adapter | 依附的适配器 |
| driver | 设备绑定的驱动 |
| irq | 设备使用的中断号 |
| dev | 内嵌的device结构体,在注册i2c_client对象时,i2c_client->dev的总线类型被指定为i2c_bus_type,其type成员被指定为i2c_client_type |

(1)struct i2c_adapter结构:用于描述索克的I2C控制器;
(二)结构i2c_algorithm结构:描述特定I2C控制器的数据通信方法,以及相关的硬件;
(三)struct i2c_msg结构:I2C子系统数据传输的基本单元,通过I2C控制器传输数据是基本单元的信息,我们希望通信的数据是按照struct i2c_msg结构填充的;
(4)结构i2c_driver结构:描述I2C驱动的结构,I2C设备驱动器是结构i2c_driver结构的结构,调用I2C核心层提供驱动器注册界面的注册;
(5)struct i2c_client structure:描述了I2C设备的结构,它在匹配I2C总线和I2C驱动器后将设备信息发送给驱动器,这里是分开驱动器设计数据的操作方法的设想;
(6)i2c_board_info结构:描述由I2C适配器驱动的支持I2C设备的信息,包括支持I2C设备的名称、I2C总线的地址、中断数据、私人数据等;
(1)定义和登记I2C总线i2c_bus_type和适配器类i2c_adapter_class;
(二)提供i2c_driver、i2c_adapter和i2c_client的分配、创建、登记、取消等服务;
(三)执行I2C通信方法的高级代码;
(四)为I2C设备的检测、添加和地址检查提供方法;
I2C核心层的注册界面功能很简单:注册I2C总线和注册I2C设备驱动程序 dummy_driver;
(1)I2C总线有两个链表,一个用于连接驱动器,另一个用于连接设备;
(2)有两个类型的设备连接到I2C:i2c_client_type和i2c_adapter_type;
(3)i2c_adapter_type表示适配器,i2c_client_type是当dap注册时i2c_board_info结构的结构;
(4)工作流程:设备在I2C总线上注册时,是否已经在I2C总线上注册的驱动器匹配,如果匹配,请调用驾驶员探测方法;当驾驶员登记到I2C巴士时,它还可以查看I2C总线上的设备是否匹配,如果匹配,请调用驱动探测方法;
I2C总线在I2C核心层的注册界面i2c_init()中注册,负责匹配I2C设备和I2C驱动器;
在将I2C驱动器或I2C设备注册到I2C总线时,I2C驱动器名称和I2C设备名称将相匹配,如果相匹配,I2C总线的探测方法将被调用;
I2C总线的探测方法没有实用功能,是匹配的I2C驱动器的探测方法;
(1)I2C适配器与硬件上的SocI2C控制器相符,在内核中,I2C控制器被认为是设备,因为有相应的驱动器,即I2C设备驱动器;
(二)I2C适配器驱动器是操作I2C控制器的基本方法,提供与I2C控制器连接的I2C设备在I2C总线上通信。
(三)I2C适配器驱动主要通过操作Soc的I2C控制器相关注册表实现数据传输;
(一)首先在平台总线上登记I2C适配器驱动程序,并以平台设备方式将I2C适配器所要求的数据传递给I2C适配器驱动程序;
(2)在S5PV210芯片中,三个I2C适配器操作方法相同,只是服务器地址和操作中断数不同,并且在平台设备中的适配器之间的差异已经转移到适配器驱动器中,因此,这些适配器通常用于i2c-s3c2410.c适配器驱动文件;
s3c24xx_i2c_probe将被调用三次,因为它将在 platform_device.dev. platform_data中使用不同的适配器来区分,在平台总线上将被调用三次;
(1)为每个struct i2c_board_info建立相应的struct i2c-devinfo结构;
(2)生成的结构i2c-devinfo结构与 __i2c_board_list链表相连;
(1)适配器适配器被视为内核中的设备,i2c_register_adapter()函数首先初始化内核内置的设备结构。
(2)在向内核注册ap时,因为dap嵌入设备结构的总线总线类型设置为i2c_bus_type,事实上,它是注册到I2C总线的设备,I2C总线的匹配函数用于与I2C总线已经注册的司机匹配,如果匹配成功,请调用I2C总线的探测函数;
(3)adap和已注册的结构i2c_board_info结构由适配器代码匹配,匹配生成结构客户端结构;
(4)adap和已经注册的I2C驱动进行逐一匹配,如果I2C驱动定义了driver->attach_adapter方法就调用;
(1)结构i2c_client结构是适配器注册时在I2C总线上的设备,由适配器适配器和匹配的结构i2c_board_info结构组成;
(2)struct i2c_client 在描述I2C设备时,I2C总线的设备类型为i2c_client_type。
(一)在 __i2c_board_list 链表上重复所有结构 i2c_devinfo 结构,并与新注册的适配器适配器的数目相匹配;
(2)如果匹配,调用i2c_new_device()函数生成基于struct i2c_devinfo结构和 adapter adapter adapter adapter的结构客户端结构;
(1) bus_for_each_drv()函数是内核总线的驱动过渡函数,该函数是已经在总线总线上注册的驱动过渡,并且调用fn匹配函数与数据匹配驱动;
(2)在i2c_register_adapter()注册函数中,公共汽车经过I2C公共汽车结构,数据是新注册的 adapter 结构 i2c_adapter 结构,匹配函数是 __process_new_adapter()函数;
(3)功能:将I2C总线上已经注册的驱动逐一和新注册的适配器adap进行匹配,匹配函数是 __process_new_adapter()函数;
__process_new_adapter()函数的实际功能是检查在I2C总线上定义的I2C驱动器是否定义了attache_adapter方法,如果定义了调用驱动程序的attache_adapter方法,输入新注册的适配器适配器作为参数;
(2)事实上,通用驱动器不是定义的attache_adapter方法,仅在i2cdev_driver驱动器中定义了attache_adapter方法,i2cdev_driver驱动器是i2c-dev.defined中的c的i2c_dev_init()函数,在博客: Device Interface Analysis of Adapters for I2C Subsystems ( i2c -dev."(c) Document Analysis)。 有详细的介绍;
(3)实际效果:每件新注册的适配器适配器适配器,都会调用i2cdev_driver->attach_adapter方法,在sysfs中创建i2c-dev类"/sys/class/i2c-dev/i2c-n(n=0, 1,..⋯)",创建设备节点"/dev/i2c-n(n=0, 1,⋯⋯)"
(1)i2c-dev.c是将I2C适配器暴露于上层应用程序的实现,表示为设备节点"/dev/i2c-n(n=0, 1, 2, ⋯⋯)",多少设备节点代表Soc的多少I2C控制器;
(二)应用程序可直接通过设备节点操作I2C适配器,以与与I2C适配器连接的设备进行通信;
(2)参考博客: Device Interface Analysis of Adapters for I2C Subsystems ( i2c -dev."(c) Document Analysis)。 ;
参考博客:S5PV210芯片I2C适配器驱动器分析(i2c-s3c2410.(c));
(一)I2C设备驱动器与特定硬件密切相关,即该设备是I2C接口,与SOC的I2C控制器连接,通过I2C总线和主控制SOC进行通信;
(二)I2C设备驱动器将I2C设备驱动器注册到I2C核心层,然后核心层将I2C总线与I2C设备驱动器匹配,并将I2C适配器驱动器与I2C设备驱动器匹配;
(3)I2C设备驱动器成功匹配I2C核心层后,设备可以直接调用I2C适配器进行数据通信;
参考博客: gslx680 Touchscreen Drive Source Code Analysis (gslX680.(c));
本文由 在线网速测试 整理编辑,转载请注明出处。