4. SPI 设备树绑定规范

在车载嵌入式 Linux 系统中,SPI 控制器的硬件拓扑、时序参数、片选映射以及从设备属性,全部通过设备树(Device Tree)进行静态描述。设备树绑定规范定义了 SPI 控制器节点(spi-controller)和 SPI 从设备子节点(spi-device)的标准属性,是驱动正确匹配与运行时配置的基础。

4.1 SPI 控制器节点(spi-controller)属性定义

SPI 控制器节点通常位于 SoC 的 AHB/APB 总线节点下,其 compatible 属性匹配具体 SPI 主机驱动。除标准总线属性外,SPI 控制器节点必须声明 #address-cells 和 #size-cells,并标识自身为 SPI 总线控制器。

属性名 类型 必需 描述
compatible string 是 匹配 SPI 主机驱动,如 "fsl,imx6q-ecspi"、"ti,omap4-mcspi"
#address-cells <u32> 是 子节点 reg 属性中地址字段的单元数,通常为 <1>
#size-cells <u32> 是 子节点 reg 属性中长度字段的单元数,通常为 <0>
reg prop-encoded-array 是 控制器寄存器基地址与地址范围
interrupts prop-encoded-array 是 SPI 控制器中断号
clocks phandle 是 SPI 模块时钟与 SPI 总线时钟的 phandle
dmas phandle 否 DMA 传输通道 phandle,用于高速 SPI 传输
cs-gpios phandle-array 否 片选 GPIO 列表,用于 GPIO 模拟片选场景
num-cs <u32> 否 硬件支持的片选数量,默认值为 1
车载场景提示: 在域控制器中,SPI 控制器通常连接多个传感器或执行器。必须确保 num-cs 与实际硬件片选线数量一致,否则驱动可能无法正确分配片选资源。

4.2 SPI 从设备子节点(spi-device)属性定义

每个 SPI 从设备在控制器节点下以一个子节点表示,通过 reg 属性指定片选编号。时序参数通过 spi-max-frequency、spi-cpha、spi-cpol 等标准属性配置。

属性名 类型 必需 描述
compatible string 是 匹配 SPI 从设备驱动,如 "microchip,mcp2515"
reg <u32> 是 片选编号(chip select index),从 0 开始
spi-max-frequency <u32> 是 SPI 总线最大时钟频率,单位 Hz
spi-cpha empty/bool 否 时钟相位(Clock Phase),存在时表示 CPHA=1
spi-cpol empty/bool 否 时钟极性(Clock Polarity),存在时表示 CPOL=1
spi-cs-high empty/bool 否 片选高电平有效,默认低电平有效
spi-3wire empty/bool 否 三线制 SPI(无 MISO/MOSI 分离)
spi-lsb-first empty/bool 否 LSB 优先传输,默认 MSB 优先
spi-tx-bus-width <u32> 否 发送数据线宽度,1/2/4,用于 Dual/Quad SPI
spi-rx-bus-width <u32> 否 接收数据线宽度,1/2/4
时序参数速记: CPOL 决定时钟空闲电平(0=低,1=高);CPHA 决定数据采样沿(0=第一个跳变沿,1=第二个跳变沿)。两者组合为 4 种 SPI 模式(Mode 0~3)。

4.3 SPI 时序模式(CPOL / CPHA)详解

SPI 总线有 4 种标准时序模式,由 spi-cpol 和 spi-cpha 两个布尔属性共同决定。车载传感器(如角度传感器、压力传感器)通常使用 Mode 0 或 Mode 3,因为这两种模式在时钟边沿采样时具有更好的噪声容限。

SPI 模式 CPOL CPHA 时钟空闲电平 数据采样沿 典型车载器件
Mode 0 0 0 低电平 第一个跳变沿(上升沿) MCP2515 CAN 控制器
Mode 1 0 1 低电平 第二个跳变沿(下降沿) 部分温度传感器
Mode 2 1 0 高电平 第一个跳变沿(下降沿) 部分 ADC 芯片
Mode 3 1 1 高电平 第二个跳变沿(上升沿) NXP 射频收发器
SPI 四种时序模式(CPOL / CPHA)波形对比 Mode 0 (CPOL=0, CPHA=0) SCLK 采样沿:上升沿 Mode 1 (CPOL=0, CPHA=1) SCLK 采样沿:下降沿 Mode 2 (CPOL=1, CPHA=0) SCLK 采样沿:下降沿 Mode 3 (CPOL=1, CPHA=1) SCLK 采样沿:上升沿 时序参数配置要点 • CPOL=0:SCLK 空闲时为低电平;CPOL=1:SCLK 空闲时为高电平 • CPHA=0:数据在第一个时钟边沿采样;CPHA=1:数据在第二个时钟边沿采样 • 车载 CAN 控制器(如 MCP2515)通常使用 Mode 0,与 SPI 主机默认模式兼容 • 高速传感器(如 10MHz 以上)推荐使用 Mode 3,减少时钟空闲跳变噪声 • 设备树中同时声明 spi-cpol 和 spi-cpha 时,驱动自动配置 SPI 模式寄存器

4.4 完整设备树节点示例

以下是一个车载域控制器中 SPI 控制器连接两个从设备的完整设备树片段。第一个从设备是 CAN 控制器(MCP2515),第二个是角度传感器(AS5048A)。

/* SPI 控制器节点 */
&ecspi1 {
    compatible = "fsl,imx6q-ecspi";
    reg = <0x02008000 0x4000>;
    interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clks IMX6Q_CLK_ECSPI1>,
             <&clks IMX6Q_CLK_ECSPI1>;
    clock-names = "ipg", "per";
    dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
    dma-names = "rx", "tx";
    #address-cells = <1>;
    #size-cells = <0>;
    cs-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>,
               <&gpio4 12 GPIO_ACTIVE_LOW>;
    status = "okay";

    /* SPI 从设备 0:MCP2515 CAN 控制器 */
    can0: can@0 {
        compatible = "microchip,mcp2515";
        reg = <0>;                     /* 片选 0 */
        spi-max-frequency = <10000000>; /* 10 MHz */
        spi-cpol;                       /* CPOL=1 */
        spi-cpha;                       /* CPHA=1 → Mode 3 */
        clocks = <&clks IMX6Q_CLK_CAN>;
        interrupt-parent = <&gpio1>;
        interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
        vdd-supply = <®_3v3>;
        xceiver-supply = <®_5v0>;
    };

    /* SPI 从设备 1:AS5048A 角度传感器 */
    angle_sensor: angle@1 {
        compatible = "ams,as5048a";
        reg = <1>;                     /* 片选 1 */
        spi-max-frequency = <5000000>;  /* 5 MHz */
        /* 不声明 spi-cpol/spi-cpha,默认 Mode 0 */
        spi-cs-high;                    /* 片选高电平有效 */
        interrupt-parent = <&gpio1>;
        interrupts = <3 IRQ_TYPE_EDGE_RISING>;
    };
};
常见配置错误: 在车载项目中,经常出现 spi-max-frequency 设置超过从设备额定频率的情况,导致数据采样错误。务必查阅器件数据手册,确保频率不超过从设备支持的最大值。另外,cs-gpios 中的 GPIO 必须与 reg 片选编号一一对应,否则片选信号无法正确拉低。

4.5 属性继承与覆盖规则

SPI 设备树属性遵循“子节点覆盖父节点”的继承规则。控制器节点可以定义默认时序参数,子节点通过显式声明覆盖默认值。驱动在解析时,优先读取子节点属性,若未定义则回退到控制器默认配置。

  • 控制器默认属性: 部分 SPI 主机驱动支持在控制器节点中定义 spi-cpol、spi-cpha 等属性作为总线默认值。
  • 子节点显式覆盖: 从设备子节点中声明的时序属性优先级最高,驱动会将其写入 SPI 控制器的模式寄存器。
  • 运行时动态调整: 内核 SPI 子系统允许在 spi_transfer 中临时修改 speed_hz、bits_per_word 等参数,但设备树中的静态配置是驱动 probe 时的初始值。
SPI 设备树属性解析优先级 SPI 控制器节点 控制器默认时序属性(可选) 从设备子节点 0 (reg=0) 从设备子节点 1 (reg=1) 子节点属性优先级 > 控制器默认属性;未定义时使用 SPI 主机驱动内置默认值

4.6 车载工程中的属性配置检查清单

在车载项目评审中,SPI 设备树配置是硬件-软件联调的常见问题点。以下检查清单可用于代码审查和硬件验证:

  1. 片选编号一致性: 子节点 reg 值必须与 cs-gpios 列表索引对应,且不能超过 num-cs 定义的数量。
  2. 频率降额设计: spi-max-frequency 建议设置为器件额定频率的 80%,预留 PCB 走线损耗裕量。
  3. 时序模式匹配: 从设备数据手册中确认 CPOL/CPHA 要求,与控制器支持的 SPI 模式交叉验证。
  4. 中断与 DMA 协同: 高速 SPI 从设备(如 10MHz 以上)建议配置 dmas 属性,避免 CPU 轮询导致实时性下降。
  5. 电源域检查: 确保 vdd-supply 等电源属性指向正确的 regulator 节点,防止 SPI 通信时电源未使能。
实战经验: 在某车载 T-Box 项目中,MCP2515 的 SPI 频率从 10MHz 提升至 12MHz 后出现间歇性 CRC 错误。通过示波器测量发现 SCLK 信号过冲超过器件容忍范围,最终将频率回调至 8MHz 并增加 PCB 串联电阻解决。设备树中的 spi-max-frequency 不仅是软件配置,更是硬件信号质量的约束条件。