4. 设备树基础:设备树语法回顾、节点与属性、reg与interrupts属性
4.1 设备树语法快速回顾
设备树(Device Tree)是一种描述硬件资源的数据结构,由节点(node)和属性(property)组成。在MIPI CSI驱动开发中,设备树是连接硬件物理连接与软件驱动的桥梁。其核心语法遵循以下规则:
- 节点(Node):以
node-name@unit-address格式定义,表示一个硬件设备或总线。 - 属性(Property):键值对,用于描述节点的特性,如地址、中断、时钟、GPIO等。
- 标签(Label):通过
label: node-name方式定义,便于在其他节点中引用。 - 包含(Include):使用
#include导入头文件或dtsi文件。
关键点: 设备树中的每个节点对应一个硬件设备,属性则描述该设备的配置参数。对于MIPI CSI,节点通常位于
soc 或 i2c 总线下。
4.2 节点与属性详解
节点是设备树的基本单元,属性则提供节点的具体信息。以下是一个典型的MIPI CSI摄像头传感器节点示例:
// 摄像头传感器节点
&i2c2 {
status = "okay";
clock-frequency = <400000>;
ov5640: camera@3c {
compatible = "ovti,ov5640";
reg = <0x3c>;
clocks = <&clks IMX8MM_CLK_CLKO2>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_csi_pwn>;
reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
powerdown-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
port {
ov5640_ep: endpoint {
remote-endpoint = <&csi_ep>;
bus-type = <MEDIA_BUS_TYPE_CSI2_CPHY>;
data-lanes = <1 2>;
clock-lanes = <0>;
clock-noncontinuous;
};
};
};
};
| 属性 | 说明 | MIPI CSI场景示例 |
|---|---|---|
compatible |
设备兼容性字符串,驱动匹配依据 | "ovti,ov5640" |
reg |
设备地址或寄存器基址 | <0x3c>(I2C地址) |
clocks |
时钟源句柄 | <&clks IMX8MM_CLK_CLKO2> |
reset-gpios |
复位GPIO | <&gpio1 8 GPIO_ACTIVE_LOW> |
port/endpoint |
端口与端点,描述数据连接 | data-lanes、clock-lanes |
实战提示: 在调试MIPI CSI时,
data-lanes 和 clock-lanes 的配置必须与硬件PCB走线完全一致,否则会导致图像采集失败或数据错位。
4.3 reg属性:地址与地址空间
reg 属性用于描述设备在总线上的地址或寄存器地址范围。其格式为 reg = <address1 length1 address2 length2 ...>。在MIPI CSI场景中,reg 通常表示I2C从设备地址或CSI控制器的寄存器基址。
// I2C设备地址示例
reg = <0x3c>; // 7位I2C地址
// 内存映射设备示例(CSI控制器)
csi: csi@32e30000 {
compatible = "fsl,imx8mm-csi";
reg = <0x32e30000 0x10000>; // 基址0x32e30000,长度0x10000
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
};
| 设备类型 | reg格式 | 说明 |
|---|---|---|
| I2C设备 | <0x3c> |
单个地址值,无长度 |
| SPI设备 | <0x0 0x100000> |
片选号 + 地址范围 |
| 内存映射设备 | <0x32e30000 0x10000> |
基址 + 映射长度 |
常见错误: I2C地址写错(如将7位地址写成8位)会导致驱动无法探测到设备。务必确认传感器数据手册中的地址格式。
4.4 interrupts属性:中断配置
interrupts 属性用于描述设备的中断信号。其格式依赖于中断控制器类型,常见格式为 interrupts = <中断号 触发类型>。在ARM GIC(通用中断控制器)中,格式为 <中断类型 中断号 触发类型>。
// GIC中断示例
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
// 简单中断控制器示例
interrupts = <10 IRQ_TYPE_EDGE_RISING>;
| 宏定义 | 值 | 说明 |
|---|---|---|
GIC_SPI |
0 | 共享外设中断 |
GIC_PPI |
1 | 私有外设中断 |
IRQ_TYPE_LEVEL_HIGH |
4 | 高电平触发 |
IRQ_TYPE_EDGE_RISING |
1 | 上升沿触发 |
调试要点: 中断号错误或触发类型不匹配会导致中断无法触发或频繁误触发。使用
cat /proc/interrupts 可验证中断是否注册成功。
4.5 设备树结构SVG图
4.6 实战:解析MIPI CSI设备树片段
以下是一个完整的MIPI CSI设备树配置片段,包含CSI主机控制器和摄像头传感器:
// CSI主机控制器节点
csi: csi@32e30000 {
compatible = "fsl,imx8mm-csi";
reg = <0x32e30000 0x10000>;
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX8MM_CLK_CSI>;
clock-names = "mclk";
status = "disabled";
port {
csi_ep: endpoint {
remote-endpoint = <&ov5640_ep>;
bus-type = <MEDIA_BUS_TYPE_CSI2_CPHY>;
data-lanes = <1 2>;
clock-lanes = <0>;
};
};
};
// I2C总线上的摄像头传感器
&i2c2 {
status = "okay";
clock-frequency = <400000>;
ov5640: camera@3c {
compatible = "ovti,ov5640";
reg = <0x3c>;
clocks = <&clks IMX8MM_CLK_CLKO2>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_csi_pwn>;
reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
powerdown-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
status = "okay";
port {
ov5640_ep: endpoint {
remote-endpoint = <&csi_ep>;
bus-type = <MEDIA_BUS_TYPE_CSI2_CPHY>;
data-lanes = <1 2>;
clock-lanes = <0>;
clock-noncontinuous;
};
};
};
};
调试步骤:
1. 确认
2. 检查
3. 验证
4. 使用
1. 确认
reg 地址与硬件原理图一致(I2C地址、寄存器基址)。2. 检查
interrupts 中断号是否与SoC手册匹配。3. 验证
data-lanes 和 clock-lanes 的lane编号与PCB走线对应。4. 使用
dtc -I dtb -O dts 反编译设备树,确认编译后的配置正确。
4.7 常见错误与排查方法
| 错误类型 | 现象 | 排查方法 |
|---|---|---|
| reg地址错误 | 驱动probe失败,设备未注册 | 核对数据手册,使用 i2cdetect 验证地址 |
| 中断号错误 | 中断不触发或系统卡死 | 检查 /proc/interrupts,对比SoC手册 |
| data-lanes配置错误 | 图像花屏或数据错位 | 确认硬件lane映射,调整lane顺序 |
| remote-endpoint不匹配 | 媒体图无法建立连接 | 检查 remote-endpoint 的phandle是否对应 |
重要提醒: 设备树编译错误(如缺少分号、括号不匹配)会导致系统无法启动。建议使用
dtc -@ -I dts -O dtb 编译时开启 -@ 选项以支持插件,并仔细检查语法。