Lazy loaded image
🥳嵌入式Linux开发
Linux 驱动专题 - IIC 驱动
Words 1682Read Time≈ 5 min
2025-4-16
2026-10-22
Linux内核提供了一套完整的I2C子系统,它采用分层设计,实现了硬件抽象,使得应用程序可以透明地访问I2C设备。
Linux I2C子系统的架构分为几个关键层次:应用层、设备驱动层、核心层和控制器驱动层。这种分层设计使得整个系统更加模块化,便于维护和扩展。
  1. 应用层:
      • 用户空间程序通常通过具体功能子系统访问设备;调试或直接访问总线时,也可通过 i2c-dev 暴露的 /dev/i2c-X 接口进行操作。
      • i2c-tools 可用于总线诊断和读写,但直接访问前应确认该地址没有被内核设备驱动管理,避免并发访问造成问题。
  1. I2C设备与设备驱动层:
      • i2c_client 表示总线上一个具体设备实例,包含设备地址等信息;它不是设备驱动。
      • 设备树等固件描述提供设备节点、地址和兼容字符串;I2C core据此创建并注册 i2c_client。设备驱动模型再依据设备树匹配表、ACPI信息或I2C设备ID等匹配对应的 i2c_driver。
      • 匹配成功后,驱动的 probe() 读取设备属性、获取所需资源并初始化芯片;若设备需要接入 input、IIO 等子系统,由设备驱动调用相应子系统接口完成注册。
  1. I2C核心层(I2C Core):
      • 提供统一的传输接口,如 i2c_transfer() 和 SMBus 接口,并将传输请求分发给对应的适配器。
      • 管理适配器、client和驱动的注册与注销,参与设备与驱动的匹配,并在匹配成功时触发 probe()。
      • 设备地址通常由设备树或板级描述给出;core负责创建和管理client,并检查地址冲突,不负责为普通I2C设备动态分配地址。
  1. 适配器/控制器驱动层:
      • 控制器驱动注册 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。以下是几个关键函数:
  1. i2c_transfer函数:I2C消息传输的核心函数
    1. __i2c_transfer函数:实际执行传输操作
       

      设计理念

      Linux I2C子系统的设计体现了以下几个关键理念:
      1. 分层架构:清晰分离应用层、驱动层、核心层和硬件控制层,每层职责明确。
      1. 设备模型集成:I2C子系统完全集成到Linux设备模型中,设备注册、发现和匹配都遵循统一的模式。
      1. 硬件抽象:通过抽象接口隔离硬件细节,使上层应用无需关心底层实现。
      1. 总线与设备分离:区分总线控制器(adapter)和总线上的设备(client),便于管理。
       
      上一篇
      Linux 驱动专题 - pinctrl 子系统
      下一篇
      Linux 驱动专题 - SPI 驱动

      Comments
      Loading...