驱动之路#44:硬件 I2C 和软件 I2C 谁更坑?
欢迎关注,每周更新!☞
本合集分享的是,我当初学习Linux驱动的来时路——《《驱动之路》开篇:自序&前言》。
正文
前面几篇文章,我们已经陆续聊了 I2C 通信机制、上拉电阻、SMBus 关系,以及 Linux I2C 子系统架构。
到这里,基本就能看懂 I2C 的大部分基础概念了。
不过实际项目里,还有一个问题也挺常见:硬件 I2C 和软件 I2C 到底有什么区别?这篇就简单聊聊硬件 I2C 和软件 I2C。
先说结论:
能用硬件 I2C,就优先用硬件 I2C;软件 I2C 不是不能用,而是更适合做补救方案。
1. I2C 通信有两种实现方式
从实现方式看,I2C 通信大致可以分成两类。
第一类是硬件 I2C。
也就是使用 SoC 内部自带的 I2C 控制器,比如 RK3576 里的 I2C0、I2C1、I2C2 等。
第二类是软件 I2C。
也就是找两个普通 GPIO,通过软件手动控制电平变化,模拟出 SDA / SCL 的时序。
简单理解:
硬件 I2C:专用控制器干活软件 I2C:CPU 控 GPIO 硬模拟
两者最终都能在 SDA / SCL 上产生 I2C 时序,也都能和 I2C 外设通信。
但实现方式、稳定性、CPU 占用、适用场景差别很大。
2. 硬件 I2C 是什么?
硬件 I2C,就是芯片内部已经集成了专门的 I2C 控制器。

以 RK3576 为例,I2C 控制器驱动一般在类似路径下:
kernel-6.1/drivers/i2c/busses/i2c-rk3x.c、
这一层驱动会对接 RK3576 内部的 I2C 硬件模块。
开发者不需要自己手动控制 SDA / SCL 的每一次翻转。
正常情况下,我们只需要:
1. 在设备树里打开对应 I2C 控制器;2. 配置 pinctrl、clock、status 等资源;3. 在该 I2C 节点下挂载从设备;4. 通过 I2C 设备驱动、i2c-tools 或 i2c_transfer 访问设备。
比如设备树里可能会看到:

真正通信时,上层只要发起传输请求,硬件控制器就会自动完成:
Start;地址发送;读写位;ACK/NACK 检测;数据收发;Stop。
传输完成后,再通过中断或者轮询通知 CPU。
所以硬件 I2C 最大的特点是:
I2C 时序由硬件保证,CPU 不用一直盯着 SDA / SCL 翻电平。
这也是为什么实际项目里,能用硬件 I2C 就优先用硬件 I2C。
3. 软件 I2C 是什么?
软件 I2C,也叫 GPIO 模拟 I2C。
它的思路很直接:
既然 I2C 本质就是 SDA / SCL 两根线的电平变化,那我用两个普通 GPIO 手动模拟这些时序,不也能通信吗?
答案是:确实可以。
比如用 GPIOA 做 SDA,用 GPIOB 做 SCL,然后软件依次模拟:
SCL 高电平时 SDA 高变低 -> StartSCL 低电平时准备数据SCL 高电平时采样数据第 9 个时钟读取 ACKSCL 高电平时 SDA 低变高 -> Stop
这就是软件 I2C 的基本原理。
Linux 内核里已经有现成的 GPIO 模拟 I2C 驱动:
drivers/i2c/busses/i2c-gpio.c

所以正常情况下,不需要自己从零写 bit-bang 时序。
在设备树里配置好 SDA / SCL 对应 GPIO 后,就可以通过 i2c-gpio 注册出一个软件模拟的 I2C adapter。
这种方案的好处是:引脚灵活。
只要有两个能正常输入输出的 GPIO,理论上就可以模拟一条 I2C 总线。
但代价也很明显:时序靠软件,CPU 要参与,稳定性更依赖系统状态。
4. 软件 I2C 为什么更容易坑?
软件 I2C 最容易坑的地方,在于它对时序非常敏感。
硬件 I2C 的时序由硬件控制器保证,SCL 拉高多久、SDA 什么时候变化、ACK 什么时候采样,这些都由硬件处理。
软件 I2C 不一样。
它需要 CPU 通过代码控制 GPIO,并通过延时函数模拟时序。
比如:
拉低 SCL;设置 SDA;延时;拉高 SCL;延时;读取 SDA;再拉低 SCL;
这套流程看起来简单,但一旦系统负载高、中断频繁、调度打断,时序就可能抖动。
在裸机里模拟 I2C 还相对可控,因为 CPU 基本只跑你的代码。
但在 Linux 系统里,情况就复杂很多。
Linux 是多任务系统,当前线程可能被调度出去,中断也可能随时进来。
所以软件 I2C 的时序很难像硬件 I2C 那样稳定。
这也是为什么软件 I2C 通常只适合低速、低数据量、非关键外设。
5. 硬件 I2C 和软件 I2C 对比
| 对比项 | 硬件 I2C | 软件 I2C |
| 实现方式 | SoC 内部 I2C 控制器 | GPIO 手动模拟时序 |
| 时序精度 | 硬件保证,比较稳定 | 依赖 CPU 延时,容易抖动 |
| CPU 占用 | 低 | 高 |
| 通信速率 | 支持 100K / 400K 等常见速率 | 通常适合低速场景 |
| 稳定性 | 较高 | 受系统负载影响 |
| 引脚灵活性 | 受 SoC 复用限制 | 两个 GPIO 即可模拟 |
| 调试难度 | 主要查 DTS、pinctrl、硬件连接 | 还要关注 GPIO 时序、延时、系统负载 |
| 适用场景 | 正式产品、核心外设 | 临时补救、低速外设、控制器不够用 |
如果再说得直白一点:
硬件 I2C:规矩、稳定、省 CPU;软件 I2C:灵活、能救急,但更容易出幺蛾子。
6. 什么时候用硬件 I2C?
绝大多数正式项目里,都应该优先使用硬件 I2C。
尤其是这些场景:
[ ] PMIC / 电源管理芯片;[ ] 触摸芯片;[ ] 摄像头 sensor;[ ] 音频 codec;[ ] 关键传感器;[ ] 需要较高通信速率;[ ] 需要长期稳定运行;[ ] 数据量相对较大。
这些外设一旦通信异常,影响可能比较大。
比如 PMIC 出问题,可能影响电源控制;触摸芯片通信异常,用户直接感知;摄像头 sensor 配置失败,图像链路起不来。
这类场景就不建议为了省事去用软件 I2C。
7. 什么时候可以考虑软件 I2C?
软件 I2C 不是不能用,只是要知道它适合什么场景。
可以考虑软件 I2C 的情况包括:
[ ] SoC 硬件 I2C 控制器数量不够;[ ] 对通信速率要求不高;[ ] 外设数据量很小;[ ] 只是读取简单状态;[ ] 临时调试验证;[ ] 硬件设计已经定型,无法改线;[ ] 某些 I2C 控制器引脚被其他功能占用。
比如挂一个低速温度传感器,几秒钟读一次数据,这种场景用软件 I2C 问题一般不大。
但如果你要高频读写数据,或者外设对时序比较敏感,那就要慎重。
8. 实际工作中的选择原则
工程上可以简单按下面几条判断。
1. 能用硬件 I2C,就别优先考虑软件 I2C;2. 核心外设、关键链路,尽量使用硬件 I2C;3. 软件 I2C 适合低速、低频、低风险场景;4. 软件 I2C 更适合救急,不适合作为默认方案;5. 如果必须用软件 I2C,最好用示波器确认 SDA / SCL 波形;6. 多设备挂载、长线通信、高速通信,不建议用软件 I2C。
这里再强调一点:软件 I2C 最大的优势是引脚灵活,不是性能强。
如果只是因为“软件 I2C 配起来好像简单”,就拿它替代硬件 I2C,后期很可能给自己埋坑。
9. Linux 里软件 I2C 怎么来的?
在 Linux 内核里,软件 I2C 并不神秘。
它仍然会注册成一个 i2c_adapter,然后接入 I2C 子系统。
也就是说,从上层看,它和硬件 I2C 很像。
比如不管底层是:i2c-rk3x.c 硬件控制器
还是:i2c-gpio.c GPIO 模拟
最终都可以向上提供一个 I2C adapter。
所以上层设备驱动一般不需要关心这条总线到底是硬件 I2C 还是软件 I2C。
设备驱动仍然可以通过:
i2c_transfer()i2c_smbus_read_byte_data()i2c_smbus_write_byte_data()
去访问外设。
区别在于,底层真正执行 master_xfer 的人不一样:
硬件 I2C:由 SoC I2C 控制器驱动完成;软件 I2C:由 i2c-gpio 通过 GPIO 翻转完成。
这也是 Linux 子系统分层的好处。
10. 总结
硬件 I2C 和软件 I2C 都能实现 I2C 通信,但定位完全不同。
一句话总结:硬件 I2C 是首选方案,软件 I2C 是补救方案。
硬件 I2C 的优势是:
时序稳定;CPU 占用低;速率更高;异常处理更完善;适合正式产品和关键外设。
软件 I2C 的优势是:
引脚灵活;不依赖专用 I2C 控制器;适合低速、低频、临时补救场景。
如果在项目里要做选择,我的建议很简单:
能用硬件 I2C,就用硬件 I2C;硬件资源确实不够,再考虑 GPIO 模拟;核心外设不要轻易用软件 I2C;软件 I2C 一定要看波形,不要只看日志。
很多时候,软件 I2C 不是不能用,而是后期调试变量太多。
硬件 I2C 主要查设备树、pinctrl、上拉、电源、地址;软件 I2C 除了这些,还要担心 GPIO 翻转时序、系统调度、中断干扰。
所以要问“硬件 I2C 和软件 I2C 谁更坑?”
我的答案是:硬件 I2C 坑在配置,软件 I2C 坑在不确定性。
(完)
下期可以继续聊:如何更好使用 I2C-Tools ?
本人专注 Linux 嵌入式全栈开发,有项目合作 / 技术支持 / 交个朋友,欢迎后台私信。
更多原创技术文章:《README 2026》。
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !