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图

设备树节点层级结构(MIPI CSI场景) / (根节点) soc@0 i2c@30a20000 csi@32e30000 clk@302c0000 ov5640@3c port endpoint 关键属性映射 • ov5640@3c: reg=<0x3c> (I2C地址), clocks, reset-gpios • csi@32e30000: reg=<0x32e30000 0x10000>, interrupts=<GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH> • endpoint: data-lanes=<1 2>, clock-lanes=<0>, remote-endpoint

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. 确认 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 编译时开启 -@ 选项以支持插件,并仔细检查语法。