3. I2C地址与仲裁机制:7位地址与10位地址格式、多主机仲裁原理、时钟同步与总线竞争
I2C总线的地址与仲裁机制是驱动开发中理解设备寻址和多主机协同工作的核心。本章将深入解析7位与10位地址的格式差异、多主机仲裁的物理层原理,以及时钟同步如何避免总线竞争。
3.1 7位地址格式与寻址流程
标准I2C总线使用7位地址,允许总线上挂载最多112个从设备(保留16个地址用于特殊用途)。地址在起始条件后由主机发送,每个从设备通过硬件比较器匹配自身地址。
3.1.1 7位地址帧结构
| 位序 | 功能 | 说明 |
|---|---|---|
| Bit 7:1 | 7位从机地址 | 高7位为设备地址,范围0x00~0x7F |
| Bit 0 | 读/写位 (R/W) | 0=主机写,1=主机读 |
主机发送地址字节后,从设备必须在第9个SCL时钟周期内拉低SDA作为应答(ACK)。若未应答(NACK),主机应发送停止条件终止传输。
reg = <0x48>; 格式。注意地址值左移1位后填入地址字节的高7位,R/W位由驱动自动填充。
3.1.2 7位地址寻址时序SVG
3.2 10位地址格式与扩展寻址
当系统中从设备数量超过112个时,I2C规范定义了10位地址扩展。10位地址使用两个字节传输,第一个字节的前5位固定为 11110 作为扩展标识。
3.2.1 10位地址帧结构
| 字节 | 位序 | 功能 | 说明 |
|---|---|---|---|
| 第1字节 | Bit 7:3 = 11110 | 10位地址扩展标识 | 固定前缀,标识后续为10位地址 |
| 第1字节 | Bit 2:1 = 地址高2位 | 10位地址的 Bit 9:8 | 与第2字节拼接成完整10位地址 |
| 第1字节 | Bit 0 = R/W | 读/写位 | 0=写,1=读 |
| 第2字节 | Bit 7:0 | 10位地址低8位 | 地址 Bit 7:0 |
reg = <0x30 0x01>; 表示10位地址0x130。
3.2.2 10位地址与7位地址对比
| 特性 | 7位地址 | 10位地址 |
|---|---|---|
| 最大设备数 | 112 | 1024 |
| 地址字节数 | 1字节 | 2字节 |
| 传输效率 | 高(少1字节开销) | 低(多1字节地址) |
| 兼容性 | 所有设备支持 | 需从设备硬件支持 |
| Linux设备树配置 | reg = <0x48>; |
reg = <0x30 0x01>; |
3.3 多主机仲裁原理
I2C总线支持多主机拓扑,即多个主机可以同时尝试控制总线。仲裁机制确保最终只有一个主机赢得总线控制权,且不会丢失数据。
3.3.1 仲裁的物理层基础
I2C总线使用开漏输出和上拉电阻结构。当多个主机同时驱动SDA线时,若某个主机输出高电平而另一个输出低电平,SDA线实际电平为低(线与特性)。仲裁过程基于“低电平优先”原则:
- 数据仲裁: 主机在SDA上逐位比较输出电平与总线实际电平。若输出高但检测到低,则该主机失去仲裁,立即释放SDA和SCL。
- 非破坏性: 失去仲裁的主机不会破坏赢得主机的数据,因为总线电平由赢得主机控制。
- 重试机制: 失去仲裁的主机应在检测到总线空闲后重新发起传输。
3.3.2 仲裁流程SVG
3.3.3 仲裁与地址匹配
仲裁不仅发生在数据阶段,也发生在地址阶段。当多个主机同时发送相同地址时,仲裁会持续到数据阶段。若地址不同,则发送低地址的主机赢得仲裁(因为地址字节的低电平位更多)。
i2c-core 已实现仲裁检测,驱动开发者只需调用标准API,无需手动处理仲裁逻辑。
3.4 时钟同步与总线竞争
时钟同步是多主机I2C系统中避免总线竞争的关键机制。它确保多个主机即使使用不同频率的时钟,也能在传输过程中同步SCL信号。
3.4.1 时钟同步原理
时钟同步基于SCL线的线与特性:
- 低电平同步: 所有主机在SCL上输出低电平后,SCL线保持低电平,直到所有主机都释放SCL(输出高电平)。最快的主机必须等待最慢的主机。
- 高电平同步: 当所有主机都释放SCL后,SCL线被上拉至高电平。此时所有主机开始计数高电平时间,但最快的主机可能先结束高电平并拉低SCL,迫使其他主机提前结束高电平。
- 结果: 最终SCL的低电平时间由最慢的主机决定,高电平时间由最快的主机决定,形成统一的同步时钟。
3.4.2 时钟同步波形SVG
3.4.3 总线竞争场景与处理
| 竞争场景 | 触发条件 | 处理方式 |
|---|---|---|
| 地址竞争 | 多主机同时发送不同从机地址 | 低地址主机赢得仲裁,高地址主机释放总线 |
| 数据竞争 | 多主机发送不同数据位 | 低电平位赢得仲裁,高电平位主机失去仲裁 |
| 起始条件竞争 | 多主机同时检测总线空闲并发送起始条件 | 时钟同步后进入地址仲裁阶段 |
| 重复起始竞争 | 多主机在传输中同时发送重复起始 | 时钟同步后重新仲裁地址 |
3.4.4 驱动开发中的时钟同步处理
在Linux I2C驱动中,时钟同步由硬件控制器自动处理,但驱动开发者需注意以下配置:
- 时钟延展: 从设备可能拉低SCL以延长低电平时间(时钟延展)。主机驱动必须支持等待SCL释放,否则会导致总线挂死。
- 超时处理: 驱动应设置SCL超时时间(通常为10ms),若SCL被长时间拉低,应复位总线。
- 设备树配置: 多主机系统中,每个主机节点应配置
clock-frequency属性,但实际同步后的时钟频率由最慢的主机决定。
clock-frequency 设置为100kHz以避免时序违规。
3.5 本章小结
I2C地址与仲裁机制是总线通信的基石:7位地址适用于大多数场景,10位地址用于大规模设备扩展;多主机仲裁通过SDA线与特性实现非破坏性竞争;时钟同步确保不同速率的主机协同工作。驱动开发者需理解这些底层原理,才能正确配置设备树地址、处理总线竞争异常,并优化多主机系统的时序参数。