2. SPI总线拓扑结构:主从模式、多从机片选、菊花链拓扑

SPI(Serial Peripheral Interface)总线在物理连接上采用主从(Master-Slave)架构,由主设备控制时钟信号并决定与哪个从设备通信。根据从设备数量和连接方式的不同,SPI 总线拓扑主要分为三种:标准主从模式、多从机独立片选模式和菊花链(Daisy-Chain)模式。理解这些拓扑结构是正确设计设备树和驱动收发逻辑的前提。

2.1 标准主从模式(单主单从)

这是最基础的 SPI 连接方式,一个主设备(通常是 SoC 的 SPI 控制器)与一个从设备直接相连。四条信号线各司其职:

信号线 全称 方向 功能描述
SCLK Serial Clock 主 → 从 由主设备产生,决定数据传输速率和时序
MOSI Master Out Slave In 主 → 从 主设备发送数据给从设备
MISO Master In Slave Out 从 → 主 从设备发送数据给主设备
CS/SS Chip Select / Slave Select 主 → 从 片选信号,低电平有效,选中后从设备开始通信
关键特征:全双工同步通信;主设备负责产生时钟和片选;从设备不能主动发起通信。
标准主从模式 SPI 拓扑 主设备 SPI Controller (SoC) 从设备 SPI Slave (Sensor/ADC) SCLK MOSI MISO CS (片选) 全双工:SCLK 每个脉冲同时收发 1 bit

2.2 多从机独立片选模式

当系统中存在多个 SPI 从设备时,最常用的拓扑是独立片选方式。所有从设备共享 SCLK、MOSI、MISO 三根总线,但每个从设备拥有独立的 CS 引脚。主设备通过拉低目标从设备的 CS 引脚来选中它,其他从设备则释放 MISO 总线(高阻态),避免总线冲突。

驱动视角:在设备树中,每个从设备都作为 SPI 控制器的子节点,通过 reg 属性指定片选编号(对应硬件 CS 引脚)。Linux SPI 核心层在发起传输前会自动控制片选信号。
多从机独立片选 SPI 拓扑 主设备 SPI Master 共享总线 从设备 1 CS0 从设备 2 CS1 从设备 3 CS2 SCLK MOSI MISO CS0 CS1 CS2 每个从设备独占 CS 引脚,共享 SCLK/MOSI/MISO

2.3 菊花链拓扑(Daisy-Chain)

菊花链拓扑用于减少主设备的 CS 引脚数量,或在需要级联多个相同类型器件时使用。在菊花链中,所有从设备共享同一组 CS 和 SCLK,但数据路径串联:主设备的 MOSI 连接到第一个从设备的 MOSI 输入,第一个从设备的 MISO 连接到第二个从设备的 MOSI 输入,以此类推,最后一个从设备的 MISO 返回主设备。

注意事项:菊花链拓扑要求从设备硬件支持“数据转发”功能(通常通过内部移位寄存器实现)。数据帧长度会随从设备数量线性增加,驱动中需要发送 N 倍于单设备的数据量才能完成一次完整通信。
SPI 菊花链拓扑 主设备 SPI Master 从设备 1 Slave #1 从设备 2 Slave #2 从设备 3 Slave #3 SCLK CS MOSI DO→DI DO→DI MISO(从3 → 主设备) 数据帧长度 = 单设备帧长度 × 从设备数量(本例为 3 倍)

2.4 三种拓扑对比

特性 标准主从模式 多从机独立片选 菊花链模式
从设备数量 1 个 N 个(受限于 CS 引脚数) N 个(受限于数据帧长度)
CS 引脚占用 1 个 N 个 1 个
数据帧长度 固定(如 8/16 bit) 固定,每个从设备独立 N 倍于单设备帧长度
通信并发性 独占总线 分时复用,一次只与一个从设备通信 所有从设备同时接收,但数据串行通过
硬件要求 标准 SPI 接口 标准 SPI 接口 + 多 CS 从设备必须支持数据转发(DO→DI)
驱动复杂度 低 中(设备树多节点) 高(需组装/解析复合帧)
典型应用 单传感器、单存储器 多传感器阵列、多外设 移位寄存器级联、LED 驱动、ADC 级联

2.5 设备树中的拓扑表达

在 Linux 设备树中,SPI 总线拓扑通过父子节点关系直接映射。以下示例展示了一个 SPI 控制器挂载两个从设备(独立片选)的设备树片段:

/* SPI 控制器节点 */
&spi1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi1_pins>;

    /* 从设备 1:温度传感器,片选 CS0 */
    temp_sensor: temperature@0 {
        compatible = "ti,tmp121";
        reg = <0>;              /* 对应 CS0 */
        spi-max-frequency = <2000000>;  /* 2 MHz */
        spi-cpol;               /* 时钟极性 = 1 */
        spi-cpha;               /* 时钟相位 = 1 */
    };

    /* 从设备 2:ADC 转换器,片选 CS1 */
    adc_device: adc@1 {
        compatible = "ti,ads1256";
        reg = <1>;              /* 对应 CS1 */
        spi-max-frequency = <1000000>;  /* 1 MHz */
        /* 使用默认 SPI 模式 0 */
    };
};
设备树要点:
• reg 属性值对应硬件片选编号,从 0 开始。
• spi-max-frequency 定义该从设备支持的最高时钟频率。
• 菊花链拓扑在设备树中通常仍使用独立节点,但驱动需通过自定义属性(如 daisy-chain-length)告知内核链中设备数量。

2.6 拓扑选择指南

  • 从设备数量 ≤ 主设备 CS 引脚数:优先使用多从机独立片选,驱动简单,调试方便。
  • 从设备数量远多于 CS 引脚,且从设备支持数据转发:考虑菊花链,但需评估帧长度增加带来的延迟。
  • 需要同时更新多个从设备输出(如 LED 驱动):菊花链可在一次 CS 周期内更新所有设备,独立片选需多次传输。
  • 对实时性要求高:独立片选模式中,每个从设备通信延迟可控;菊花链的帧长度随设备数线性增长,延迟增加。