03 I2C 通信
I2C子系统
I2C是一个同步、半双工、串行外设通信接口,I2C接口由两根线构成,分别是SCL和SDA,采用高位先行(MSB First)的传输顺序(SPI可高位先行,也可低位先行),传输速度取决了SCL的频率。在Linux操作系统中,I2C子系统(I2C Subsystem)是内核中用于管理I2C总线控制器(Adapter)、I2C设备(Client)以及驱动程序(Driver)的核心框架,负责完成I2C设备的注册、匹配、通信和统一管理。开发者可通过Linux内核源码目录 <Linux内核源码>/Documentation/i2c获取I2C子系统的详细设计说明及接口文档。
I2C 子系统主要由以下几个部分组成:
- sysfs接口
Linux I2C 子系统通过sysfs文件系统向用户空间暴露设备信息和配置接口。其中,/sys/bus/i2c/devices目录用于展示系统中已注册的I2C适配器及挂载的I2C设备信息,包括设备地址、驱动绑定关系以及运行状态等。用户可通过读取或写入相关sysfs节点,实现设备信息查询、驱动绑定与解绑以及设备管理等操作。
- I2C 字符设备节点
Linux 内核通常会在/dev目录下创建设备节点,例如/dev/i2c-0、/dev/i2c-3 等,对应不同的I2C适配器。这些字符设备节点为用户空间程序提供标准访问接口,应用程序可通过 open()、ioctl()、read()、write() 等系统调用与指定 I2C 总线上的从设备进行通信,从而完成寄存器读写、设备配置及数据交互等操作。

提示
I2C 速率可通过修改 DTS 中 i2c_bus0 节点的 clock-frequency 属性进行调整。修改后需重新编译内核并烧录。
sysfs接口
检测 I2C 总线
# 查看系统中可用的 I2C 总线
ls /dev/i2c-*预期输出:
/dev/i2c-0 /dev/i2c-1 /dev/i2c-2 /dev/i2c-3# 查看 I2C 控制器
cat /sys/class/i2c-adapter/i2c-0/name预期输出:
lotus-i2c安装 i2c-tools
扫描总线上的设备 (i2cdetect)
dmesg -n 2
# 扫描 I2C 总线 1 上的所有设备(地址范围 0x03 ~ 0x77)
i2cdetect -y 1预期输出:
i2cdetect: warning: can't use SMBus quick write command, will skip some addresses
0 1 2 3 4 5 6 7 8 9 a b c d e f
00:
10:
20:
30: 30 -- -- -- -- -- -- --
40:
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60:
70:提示
输出中 UU 表示该地址设备已被内核驱动占用,-- 表示未检测到设备,十六进制数值表示检测到的设备地址(如 30 表示地址 0x30 的设备)
读取寄存器 (i2cget)
# 读取总线 1 上地址为 0x30 的设备的 0x00 寄存器(1 字节)
i2cget -y 1 0x30 0x00# 读取总线 1 上地址为 0x30 的设备的 0x00 寄存器(2 字节,word 模式)
i2cget -y 1 0x30 0x00 w写入寄存器 (i2cset)
# 向总线 1 上地址为 0x30 的设备的 0x10 寄存器写入 0xaa
i2cset -y 1 0x30 0x10 0xaa# 验证写入结果
i2cget -y 1 0x30 0x10批量读取寄存器 (i2cdump)
# 从总线 1 上地址为 0x30 的设备读取 256 字节数据
i2cdump -y 1 0x30