📖 推荐阅读:《Yocto项目实战教程:高效定制嵌入式Linux系统》
🎥 更多学习视频请关注 B 站:嵌入式Jerry
【内核基础精讲】I2C 子系统核心概念与结构全解析
**适用人群:**嵌入式开发/BSP/驱动开发/面试复习
**目标:**建立权威理解,彻底厘清架构、对象模型及常见误区
一、I2C 子系统的本质是什么?
1.1 I2C 是什么?
- I2C(Inter-Integrated Circuit):一种广泛应用于芯片间通信的串行总线协议,硬件上通过 SDA/SCL 两根线实现主从通信。
- 典型应用:EEPROM、音频芯片、传感器、PMIC、电源管理等外设。
1.2 Linux I2C 子系统的设计目标
- 屏蔽硬件差异:统一管理所有 I2C 控制器和挂载外设。
- 支持自动识别与驱动适配:通过标准对象、API、注册流程,使驱动开发和系统集成更高效、可维护。
二、I2C 子系统的标准对象模型(三层结构)
2.1 三层对象结构(标准表达)
层级 | 对象结构体 | 代表什么? | 作用/特征 |
---|---|---|---|
适配器层 | i2c_adapter | 一条 I2C 总线控制器(如 SOC 控制器) | 负责与底层硬件通信,封装具体时序/算法 |
设备层 | i2c_client | 每个 I2C 外设(如 EEPROM) | 代表一个地址唯一、可通信的设备,挂载于某一 adapter 上 |
驱动层 | i2c_driver | 管理某类设备的驱动逻辑 | 完成协议实现、功能实现,和 client 自动匹配并 probe |
- 三层对象通过 i2c-core 实现注册、管理、匹配和标准 API 封装。
2.2 i2c-core 的作用(避免误区)
- 不是一层对象!而是三层 glue code(管理/调度平台)。
- 完成所有对象注册、自动匹配(match/probe)、设备树解析、API 调用等核心框架工作。
三、对象注册与自动匹配机制
3.1 适配器注册
- 驱动注册(如
i2c_imx
、i2c_designware
)时,通过i2c_add_adapter()
将适配器对象注册进内核。 - 支持设备树解析、自动扫描/注册挂载的 i2c_client。
3.2 驱动注册
- 通过
i2c_register_driver()
,注册 i2c_driver 到 i2c_bus_type。 - 系统自动查找匹配的 client,调用 probe 完成驱动绑定。
3.3 设备节点注册
- 支持静态板级注册和设备树自动解析(常见于嵌入式平台)。
- 设备节点(client)注册成功后,等待对应 driver 匹配并 probe。
四、标准 API 与用户空间接口
4.1 标准内核 API
i2c_transfer()
、i2c_smbus_read_byte()
、i2c_master_send()
、i2c_master_recv()
等,驱动开发统一调用,屏蔽硬件差异。
API 名称 | 作用说明 | 调用场景举例 | 参数核心 |
---|---|---|---|
i2c_transfer() | 最底层通用 I2C 消息收发接口,支持读写混合 | 驱动自定义复杂协议/批量读写 | adapter, msgs, num |
i2c_master_send() | 单次向设备发送一段数据 | 写寄存器、EEPROM 写入等 | client, buf, count |
i2c_master_recv() | 单次从设备读取一段数据 | 读寄存器、EEPROM 读取等 | client, buf, count |
i2c_smbus_read_byte() | 以 SMBus 协议单字节读,常用于简单传感器 | 读取温度/ID/状态等单字节 | client |
i2c_smbus_write_byte() | 以 SMBus 协议单字节写,常用于简单寄存器操作 | 设置标志、发命令等 | client, value |
i2c_smbus_read_word_data() | SMBus 协议单寄存器两字节读 | 读取16位寄存器 | client, reg |
i2c_smbus_write_word_data() | SMBus 协议单寄存器两字节写 | 写16位寄存器 | client, reg, value |
4.2 用户空间访问
/dev/i2c-x
设备节点(由i2c-dev
驱动创建)。- 用户空间程序可用 ioctl/read/write 与内核 I2C 子系统通信,调试、自动化配置常用。
五、常见概念易混点&澄清
5.1 “i2c-core”是对象层吗?
- **不是!**它是管理 glue code(核心调度平台),而不是 adapter/client/driver 之外的“第四层”。
5.2 “虚拟总线”“总线设备模型”是I2C专有的吗?
- **不是!**是 Linux 设备模型的通用抽象(bus_type/device/driver),I2C 只是在其基础上实现 adapter/client/driver 的三层分层。
5.3 “i2c_client”/“i2c_driver”可以一对多吗?
- 一个 i2c_driver 可支持多个 i2c_client(同类不同设备)。
- 每个 i2c_client 只能有一个“当前驱动”与之匹配 probe。
5.4 “设备树节点”与 “i2c_client” 的关系?
- 每个设备树下的 I2C 外设节点,都会被内核解析生成一个 i2c_client 对象,挂载到指定 adapter 下,等待 driver 匹配。
六、I2C 子系统核心框架图(助记)
[i2c_adapter] <----> [i2c_client] <----> [i2c_driver]
| | |
硬件控制器 外设设备 驱动协议实现
(i2c-imx等) (eeprom等) (at24.c等)
| | |
+---------------- i2c-core --------------+
(注册、管理、匹配、API调度)
七、权威一句话总结
Linux I2C 子系统采用 adapter/client/driver 三层对象模型,由 i2c-core 实现所有对象的注册、匹配和数据调度,通过标准 API 和设备树自动支持硬件多样性,是驱动开发和系统移植的核心基础。
📖 推荐阅读:《Yocto项目实战教程:高效定制嵌入式Linux系统》
🎥 更多学习视频请关注 B 站:嵌入式Jerry