1. Linux I2C设备驱动概述
I2C(Inter-Integrated Circuit)总线是嵌入式系统中最常用的串行通信协议之一,它只需要两根线(SDA和SCL)就能实现主从设备之间的数据传输。在Linux系统中,I2C设备驱动开发是嵌入式工程师必须掌握的核心技能。
我从事Linux驱动开发已有8年时间,从早期的2.6内核到现在的5.x内核,I2C子系统经历了多次重构但核心架构保持稳定。在实际项目中,无论是传感器、EEPROM还是各种外设芯片,I2C都是首选的通信接口。本文将基于最新稳定内核版本,分享I2C设备驱动的完整开发流程和实战经验。
2. I2C总线协议基础
2.1 I2C物理层特性
I2C总线由两根双向开漏线组成:
- SCL(Serial Clock):时钟线,由主设备控制
- SDA(Serial Data):数据线,用于双向数据传输
标准模式速率为100kHz,快速模式可达400kHz,高速模式3.4MHz。实际项目中我常用示波器测量波形质量,特别是上升沿时间必须满足协议要求。例如在400kHz速率下,上升时间应小于300ns。
注意:总线必须接上拉电阻,典型值在2.2kΩ到10kΩ之间。我曾遇到因上拉电阻过大导致波形畸变的问题,最终通过减小电阻值解决。
2.2 I2C协议帧结构
一个完整的I2C传输包含:
- 起始条件(S):SCL高电平时SDA由高变低
- 7位从机地址 + R/W位
- 应答位(ACK/NACK)
- 数据字节(8位)
- 停止条件(P):SCL高电平时SDA由低变高
在调试驱动时,我习惯先用逻辑分析仪捕获原始波形,确认时序符合预期后再进行代码开发。以下是典型读操作时序:
code复制[Start][Addr+W][ACK][RegAddr][ACK][Start][Addr+R][ACK][Data][NACK][Stop]
3. Linux I2C子系统架构
3.1 内核I2C核心层
Linux内核的I2C子系统采用分层架构:
- I2C核心:提供总线注册、设备匹配等基础设施
- I2C适配器驱动:针对具体SoC的控制器驱动
- I2C设备驱动:具体的从设备驱动
关键数据结构:
c复制struct i2c_adapter;
