4. 设备树进阶语法

本章深入解析全志T113平台设备树中与硬件控制核心相关的进阶绑定语法。掌握中断、GPIO、时钟与复位的设备树描述方式,是编写正确且可移植的板级支持包(BSP)的关键。我们将从控制器声明、客户端绑定到映射机制,逐一拆解。

4.1 中断控制器(interrupt-controller)与中断映射(interrupt-map)

中断系统是SoC与外设通信的核心异步机制。在设备树中,中断的传递路径通过中断控制器和中断映射来描述。

4.1.1 中断控制器节点声明

一个能够接收并转发中断的硬件单元(如GIC、INTC)需要在设备树中声明为中断控制器。全志T113使用ARM Cortex-A7内核,其标配的通用中断控制器(GIC)是顶层中断节点。

属性含义示例值(T113 GIC)
interrupt-controller空属性,声明该节点为中断控制器必须存在
#interrupt-cells指定中断描述符所需的cell数量3(GIC标准:类型、触发、优先级)
interrupts父中断控制器的中断线(级联时使用)可选
全志T113 GIC节点示例:
gic: interrupt-controller@01c81000 {
    compatible = "arm,cortex-a7-gic";
    reg = <0x01c81000 0x1000>,
          <0x01c82000 0x2000>;
    interrupt-controller;
    #interrupt-cells = <3>;
    #address-cells = <0>;
};

4.1.2 中断客户端绑定

外设节点通过interrupts属性描述其连接到哪个中断控制器的哪条中断线。对于GIC,3个cell分别表示:

  • Cell 1(中断类型):0 = SPI(共享外设中断),1 = PPI(私有外设中断)
  • Cell 2(中断号):SPI中断号范围32~1019,PPI中断号范围16~31
  • Cell 3(触发类型与极性):1 = 上升沿触发,4 = 高电平触发
实战提示:全志T113的SPI中断号从32开始偏移。例如,UART0的中断在数据手册中为32,设备树中填写<0 32 4>。

4.1.3 中断映射(interrupt-map)

当存在多个中断控制器级联(如GIC下挂一个GPIO中断控制器)或PCIe桥接时,需要使用interrupt-map将子节点的中断请求重新映射到父中断控制器。映射表通常包含地址、中断号、父控制器句柄及父中断描述符。

注意:全志T113的GPIO模块内部集成了中断功能,通常不通过interrupt-map级联,而是直接作为GIC的子节点。但在复杂多核或异构系统中,interrupt-map是必备技能。
中断控制器层级与映射流程 GIC (中断控制器) #interrupt-cells = <3> UART0 interrupts = <0 32 4> GPIO 控制器 interrupts = <0 49 4> TWI0 interrupts = <0 38 4> 中断映射:子节点通过 interrupts 属性描述中断线,由父中断控制器(GIC)统一管理 interrupt-map 用于桥接或级联场景,将子中断域映射到父中断域

4.2 GPIO控制器(gpio-controller)与GPIO映射(gpio-map)

GPIO是嵌入式系统中最灵活的引脚资源。全志T113拥有多个GPIO bank(PA、PB、PC...),每个bank在设备树中都是一个独立的GPIO控制器节点。

4.2.1 GPIO控制器节点声明

每个GPIO bank节点必须包含以下关键属性:

属性含义示例值(T113 PA bank)
gpio-controller空属性,声明该节点为GPIO控制器必须存在
#gpio-cells指定GPIO描述符所需的cell数量2(引脚号 + 标志)
interrupts该bank连接到GIC的中断线<0 49 4>
ngpios该bank包含的GPIO数量32
全志T113 GPIO控制器节点示例(PA bank):
pio: pinctrl@02000000 {
    compatible = "allwinner,sun8i-t113-pinctrl";
    reg = <0x02000000 0x400>;
    interrupts = <0 49 4>,
                 <0 50 4>,
                 <0 51 4>,
                 <0 52 4>;
    clocks = <&ccu CLK_BUS_PIO>;
    gpio-controller;
    #gpio-cells = <2>;
    interrupt-controller;
    #interrupt-cells = <3>;
    ngpios = <32>;
};

4.2.2 GPIO客户端绑定

外设或板级设备通过gpios或cs-gpios等属性引用GPIO引脚。2个cell的格式为:

  • Cell 1(引脚号):相对于该bank的偏移,PA0为0,PA1为1,依此类推
  • Cell 2(标志):低电平有效(GPIO_ACTIVE_LOW = 1)或高电平有效(GPIO_ACTIVE_HIGH = 0)
实战示例:LED连接到PA10,高电平点亮:
led {
    compatible = "gpio-leds";
    led-0 {
        label = "status";
        gpios = <&pio 10 0>;  /* PA10, 高电平有效 */
        default-state = "off";
    };
};

4.2.3 GPIO映射(gpio-map)

与中断映射类似,gpio-map用于在多个GPIO控制器之间建立映射关系,常见于GPIO扩展芯片或复杂SoC的引脚复用场景。全志T113的pinctrl内部已经处理了bank间的切换,通常不需要显式使用gpio-map,但理解其原理有助于调试。

GPIO控制器与客户端绑定关系 PA Bank #gpio-cells = <2> ngpios = <32> PB Bank #gpio-cells = <2> ngpios = <32> PC Bank #gpio-cells = <2> ngpios = <32> LED (PA10) gpios = <&pio 10 0> 按键 (PB2) gpios = <&pio 34 1> SPI CS (PC3) cs-gpios = <&pio 67 0>

4.3 时钟(clock)与复位(reset)绑定

时钟和复位是SoC内部模块正常工作的基础保障。设备树通过标准化的bindings描述外设与时钟/复位控制器之间的依赖关系。

4.3.1 时钟绑定

全志T113的时钟系统由CCU(Clock Control Unit)统一管理。外设节点通过clocks和clock-names属性引用所需的时钟源。

属性含义示例
clocks时钟句柄列表,按顺序引用<&ccu CLK_BUS_UART0>
clock-names时钟名称列表,与clocks一一对应"apb"
assigned-clocks需要由内核初始化的时钟<&ccu CLK_UART0>
assigned-clock-rates为assigned-clocks指定的目标频率<24000000>
全志T113 UART0节点时钟绑定示例:
uart0: serial@02500000 {
    compatible = "allwinner,sun8i-t113-uart";
    reg = <0x02500000 0x400>;
    interrupts = <0 32 4>;
    clocks = <&ccu CLK_BUS_UART0>,
             <&ccu CLK_UART0>;
    clock-names = "apb", "uart";
    assigned-clocks = <&ccu CLK_UART0>;
    assigned-clock-rates = <24000000>;
    status = "disabled";
};

4.3.2 复位绑定

复位控制器(RST)确保外设在上电或驱动加载时处于已知状态。外设通过resets和reset-names属性引用复位信号。

属性含义示例
resets复位句柄列表<&ccu RST_BUS_UART0>
reset-names复位名称列表"rst"
最佳实践:在驱动probe函数中,先解除复位(deassert reset),再使能时钟。顺序错误可能导致外设无法正确初始化。

4.3.3 时钟与复位的协同工作

一个完整的外设节点通常同时包含时钟和复位绑定。内核的通用时钟框架(CCF)和复位框架会自动管理这些资源的使能与顺序。

常见错误:遗漏assigned-clock-rates可能导致外设工作频率异常;遗漏resets可能导致模块无法从异常状态恢复。
时钟与复位绑定流程 CCU 时钟控制单元 提供时钟 + 复位 UART0 clocks = <&ccu ...> resets = <&ccu ...> 驱动初始化顺序 1. 复位控制器解除复位(deassert reset) 2. 时钟控制器使能时钟(clk_prepare_enable) 3. 外设寄存器访问与配置

4.4 本章小结

本章覆盖了设备树进阶语法的四个核心领域:

  • 中断控制器与映射:理解GIC的#interrupt-cells格式,掌握interrupt-map在级联场景中的应用。
  • GPIO控制器与映射:掌握gpio-controller和#gpio-cells的声明,熟练使用gpios属性绑定外设。
  • 时钟绑定:通过clocks、clock-names和assigned-clock-rates精确控制外设工作频率。
  • 复位绑定:使用resets属性确保外设从已知状态启动,避免初始化失败。