I2C设备树参数详解
I2C设备树文件结构概述
以下是I2C设备树文件的深度解析,包含一个完整的示例(含两个I2C设备)及字段含义说明:
I2C设备树由两部分组成:
- I2C控制器节点:描述I2C主机控制器的硬件资源
- I2C从设备子节点:描述连接到该控制器的I2C设备
设备树通过属性(Properties)定义硬件参数,内核通过设备树解析器将其转换为i2c_adapter
和i2c_client
结构体,最终实现驱动匹配和硬件初始化。
I2C设备树示例(含两个I2C设备)
/ {/* 系统根节点 */aliases {i2c0 = &i2c_controller; /* 为I2C控制器添加别名,方便引用 */};i2c_controller: i2c@12340000 {/* I2C控制器节点 */compatible = "vendor,i2c-controller"; /* 控制器驱动匹配字符串 */reg = <0x12340000 0x1000>; /* 控制器寄存器基地址及大小 */interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; /* 中断号及触发方式 */clocks = <&clk_ctrl 0x5678>; /* 引用时钟控制器节点及时钟ID */clock-names = "i2c_clk"; /* 时钟名称 */#address-cells = <1>; /* 子设备地址占用的32位单元数 */#size-cells = <0>; /* 子设备大小占用的32位单元数(0表示不使用) */status = "okay"; /* 使能控制器 */clock-frequency = <400000>; /* I2C总线标准速度400kHz *//* GPIO引脚复用配置(如果需要) */pinctrl-names = "default";pinctrl-0 = <&i2c_pins>; /* 引用引脚配置节点 *//* 第一个I2C设备(温度传感器) */temp_sensor@48 {compatible = "vendor,temp-sensor"; /* 设备驱动匹配字符串 */reg = <0x48>; /* I2C从设备地址 */status = "okay"; /* 使能设备 */measurement-delay = <100>; /* 测量延迟100ms */resolution = <12>; /* 测量分辨率12位 */};/* 第二个I2C设备(EEPROM) */eeprom@50 {compatible = "vendor,eeprom"; /* 设备驱动匹配字符串 */reg = <0x50>; /* I2C从设备地址 */status = "okay"; /* 使能设备 */pagesize = <32>; /* 页大小32字节 */size = <0x2000>; /* EEPROM总大小8KB */write-timeout = <5>; /* 写超时时间5ms */};};
};
关键字段含义详解
1. I2C控制器节点字段
字段 | 含义 |
---|---|
compatible | 控制器驱动匹配字符串,用于与i2c_adapter 的of_match_table 匹配 |
reg | 控制器寄存器基地址和大小,格式为<address size> |
interrupts | 中断号及触发方式,如<GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH> |
clocks | 引用时钟控制器节点及时钟ID,用于配置I2C控制器时钟 |
clock-names | 时钟名称,与clocks 数组顺序对应 |
#address-cells | 子设备地址占用的32位单元数,通常为1 (使用I2C地址) |
#size-cells | 子设备大小占用的32位单元数,通常为0 (不使用) |
status | 控制器状态,"okay" 表示使能,"disabled" 表示禁用 |
clock-frequency | I2C总线时钟频率(Hz),常见值:100000(标准模式)、400000(快速模式) |
pinctrl-0 | 引用GPIO引脚配置节点,用于设置I2C的SDA和SCL引脚复用 |
2. I2C从设备子节点字段
字段 | 含义 |
---|---|
compatible | 设备驱动匹配字符串,用于与i2c_driver 的of_match_table 匹配 |
reg | I2C从设备地址(7位或10位),格式为<address> |
status | 设备状态,"okay" 表示使能,"disabled" 表示禁用 |
clock-frequency | 设备特定的总线频率(覆盖控制器默认值) |
pagesize | 内存页大小(针对存储器设备),影响突发写操作的最大字节数 |
size | 设备总大小(针对存储器设备),单位为字节 |
write-timeout | 写操作超时时间(ms),用于等待设备完成内部写周期 |
drive-open-drain | 开漏驱动模式,空属性启用(某些设备需要特殊驱动模式) |
pullup | 启用上拉电阻,空属性启用(某些I2C设备需要外部上拉) |
3. 其他常见字段
i2c-scl-rising-time-ns
: SCL上升时间(纳秒),用于高速模式配置i2c-scl-falling-time-ns
: SCL下降时间(纳秒),用于高速模式配置i2c-10bit-address
: 使用10位I2C地址(默认7位)keep_reset_after_probe
: 探测后保持复位状态(某些设备需要特殊初始化)
设备树解析与驱动匹配流程
-
控制器初始化:
- 内核通过
of_platform_populate()
解析设备树,将控制器节点转换为platform_device
- 匹配
platform_driver
,调用probe
函数创建i2c_adapter
并注册到I2C子系统
- 内核通过
-
设备自动创建:
- 控制器驱动调用
of_i2c_register_devices()
遍历子节点,生成i2c_client
实例 - 解析子节点属性,设置
i2c_client
的addr
、flags
、adapter
等参数
- 控制器驱动调用
-
驱动匹配:
i2c_client
通过i2c_bus_type
总线与i2c_driver
匹配,基于compatible
属性- 匹配成功后调用
i2c_driver
的probe
函数完成设备初始化
实际应用注意事项
-
总线速度配置:
clock-frequency
需与设备规格一致,高速设备可通过子节点单独设置- 某些控制器支持动态调整总线速度,通过
i2c_adapter
的set_bus_speed
方法实现
-
地址冲突:
- 同一I2C总线上的所有设备
reg
值必须唯一 - 10位地址设备需显式声明
i2c-10bit-address
属性
- 同一I2C总线上的所有设备
-
电气特性:
- SDA/SCL引脚需外接上拉电阻(通常4.7kΩ),开漏输出模式
- 长距离通信需考虑信号完整性,可能需要降低总线速度或增加上拉强度
-
调试工具:
- 使用
dmesg | grep i2c
查看I2C设备注册信息 - 通过
/sys/bus/i2c/devices/i2c-X/
目录查看控制器信息 - 通过
i2cdetect -y X
命令扫描总线上的设备(X为控制器编号) - 使用
i2cget
/i2cset
工具读写I2C设备寄存器
- 使用
总结
I2C设备树文件通过分层结构描述控制器和设备的硬件参数,内核通过设备树解析器自动生成i2c_adapter
和i2c_client
,实现驱动与硬件的无缝对接。理解各字段含义和解析流程是开发I2C驱动的关键,结合实际硬件规格和调试工具可快速定位问题。