Linux内核提供了一套完整的I2C子系统,它采用分层设计,实现了硬件抽象,使得应用程序可以透明地访问I2C设备。
Linux I2C子系统的架构分为几个关键层次:应用层、设备驱动层、核心层和控制器驱动层。这种分层设计使得整个系统更加模块化,便于维护和扩展。
- 应用层:
- 用户空间程序通常通过具体功能子系统访问设备;调试或直接访问总线时,也可通过
i2c-dev暴露的/dev/i2c-X接口进行操作。 i2c-tools可用于总线诊断和读写,但直接访问前应确认该地址没有被内核设备驱动管理,避免并发访问造成问题。
- I2C设备与设备驱动层:
i2c_client表示总线上一个具体设备实例,包含设备地址等信息;它不是设备驱动。- 设备树等固件描述提供设备节点、地址和兼容字符串;I2C core据此创建并注册
i2c_client。设备驱动模型再依据设备树匹配表、ACPI信息或I2C设备ID等匹配对应的i2c_driver。 - 匹配成功后,驱动的
probe()读取设备属性、获取所需资源并初始化芯片;若设备需要接入input、IIO等子系统,由设备驱动调用相应子系统接口完成注册。
- I2C核心层(I2C Core):
- 提供统一的传输接口,如
i2c_transfer()和 SMBus 接口,并将传输请求分发给对应的适配器。 - 管理适配器、client和驱动的注册与注销,参与设备与驱动的匹配,并在匹配成功时触发
probe()。 - 设备地址通常由设备树或板级描述给出;core负责创建和管理client,并检查地址冲突,不负责为普通I2C设备动态分配地址。
- 适配器/控制器驱动层:
- 控制器驱动注册
i2c_adapter,表示其管理的I2C总线段,并提供底层传输算法,将core的请求转换为具体控制器操作。 - GPIO模拟I2C驱动通过GPIO对SCL、SDA进行软件时序控制,也可以注册为一个适配器。
下面对设备驱动层、核心层总线驱动匹配机制以及控制器驱动有源码分析。
IIC 驱动专题01 - 设备驱动 at24.c 源码分析IIC 驱动专题02 - I2C总线驱动匹配机制分析IIC 驱动专题03 - 控制器驱动 i2c-imx.c 源码分析IIC 驱动专题04 - I2C Adpater驱动框架与实例IIC 驱动专题05 - GPIO模拟I2C源码分析和实例核心数据结构
i2c_adapter是对一段 I2C 总线的抽象,由控制器驱动注册;它通常对应一个硬件控制器管理的总线段,但不等同于控制器驱动本身。GPIO 模拟 I2C 驱动也可以注册一个 adapter。
i2c_client表示挂在该总线段上的一个具体 I2C 设备;i2c_driver则是与该设备匹配、实现设备功能的驱动。
设备注册流程
数据传输流程
Linux内核中的I2C核心实现位于
drivers/i2c/i2c-core.c。以下是几个关键函数:- i2c_transfer函数:I2C消息传输的核心函数
- __i2c_transfer函数:实际执行传输操作
设计理念
Linux I2C子系统的设计体现了以下几个关键理念:
- 分层架构:清晰分离应用层、驱动层、核心层和硬件控制层,每层职责明确。
- 设备模型集成:I2C子系统完全集成到Linux设备模型中,设备注册、发现和匹配都遵循统一的模式。
- 硬件抽象:通过抽象接口隔离硬件细节,使上层应用无需关心底层实现。
- 总线与设备分离:区分总线控制器(adapter)和总线上的设备(client),便于管理。
- Author:felixfixit
- URL:http://www.felixmicrospace.top/article/linux_i2c_driver_guide
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!






