1. VxWorks SPI 子系统概述

SPI(Serial Peripheral Interface)是一种全双工、同步、主从式的串行通信总线,广泛用于嵌入式系统中连接传感器、ADC/DAC、存储器、显示控制器等外设。VxWorks 作为实时操作系统,提供了层次清晰的 SPI 驱动框架,帮助开发者快速实现与从设备的可靠通信。

1.1 SPI 总线协议简介

SPI 总线由四根信号线组成:

  • SCLK(Serial Clock):主设备产生的同步时钟信号。
  • MOSI(Master Out Slave In):主设备输出、从设备接收数据线。
  • MISO(Master In Slave Out):从设备输出、主设备接收数据线。
  • CS/SS(Chip Select / Slave Select):片选信号,低电平有效,用于选择目标从设备。

SPI 协议有四种工作模式,由时钟极性(CPOL)和时钟相位(CPHA)组合决定:

模式 CPOL CPHA 数据采样边沿 典型应用
模式 0 0 0 上升沿采样 多数 SPI Flash、传感器
模式 1 0 1 下降沿采样 某些 ADC 器件
模式 2 1 0 下降沿采样 部分 EEPROM
模式 3 1 1 上升沿采样 高速 SPI 设备
开发提示: 在编写 SPI 驱动时,务必查阅从设备数据手册确认其支持的 SPI 模式。模式不匹配会导致通信数据错位或完全失败。
SPI 总线主从连接拓扑 主设备 (Master) SCLK 发生器 从设备 1 (Slave) 从设备 2 (Slave) 从设备 N SCLK MOSI MISO CS 每个从设备独占一根 CS 线 SCLK/MOSI/MISO 可共享

1.2 VxWorks SPI 框架层次

VxWorks 的 SPI 驱动框架采用分层设计,从底层硬件到上层应用分为四个层次:

  1. 硬件层(Hardware Layer):SPI 控制器寄存器操作、时钟配置、GPIO 片选控制。
  2. 总线驱动层(Bus Driver Layer):实现 SPI 控制器初始化、数据传输、中断处理,向上提供标准接口。
  3. 核心层(Core Layer):VxWorks 提供的 SPI 核心框架,管理设备注册、消息队列、传输调度。
  4. 从设备驱动层(Slave Device Driver Layer):针对具体 SPI 从设备(如 Flash、传感器)实现的驱动,调用核心层 API 完成通信。
VxWorks SPI 驱动框架层次 应用层(Application) 从设备驱动层(Slave Device Driver) SPI 核心层(Core Layer) SPI 总线驱动层(Bus Driver)
架构要点: 从设备驱动层不直接操作硬件寄存器,而是通过核心层提供的 API(如 spiMsgSend、spiMsgRecv)发起传输。这种分层设计使得驱动代码可移植性高,更换 MCU 平台时只需重写总线驱动层。

1.3 SPI 核心数据结构

VxWorks SPI 核心层定义了若干关键数据结构,驱动开发者必须理解这些结构才能正确编写从设备驱动。

1.3.1 SPI_DEVICE 结构体

每个 SPI 从设备对应一个 SPI_DEVICE 实例,描述设备的硬件连接和通信参数:

typedef struct spi_device {
    UINT32      chipSelect;      /* 片选 GPIO 编号或索引 */
    UINT32      mode;            /* SPI 模式 (0~3) */
    UINT32      bitsPerWord;     /* 每字位数,通常为 8 */
    UINT32      maxSpeedHz;      /* 最大时钟频率 (Hz) */
    UINT32      flags;           /* 标志位,如 SPI_DEVICE_3WIRE */
    void       *controller;      /* 指向所属 SPI 控制器 */
    /* ... 其他内部字段 */
} SPI_DEVICE;

1.3.2 SPI_MSG 结构体

SPI 消息结构体用于封装一次传输操作,支持同时发送和接收:

typedef struct spi_msg {
    UINT8      *txBuf;           /* 发送数据缓冲区 */
    UINT8      *rxBuf;           /* 接收数据缓冲区 */
    UINT32      len;             /* 传输字节数 */
    UINT32      csChange;        /* 传输完成后是否释放片选 */
    UINT32      delayUsecs;      /* 传输间延迟 (微秒) */
    void       *context;         /* 用户上下文 */
    /* ... 其他内部字段 */
} SPI_MSG;

1.3.3 SPI_CONTROLLER 结构体

SPI 控制器结构体代表一个 SPI 硬件控制器实例,包含操作函数指针表:

typedef struct spi_controller {
    UINT32      busNum;          /* 总线编号 */
    STATUS    (*transfer)(struct spi_controller *ctrl,
                          struct spi_device *dev,
                          struct spi_msg *msg);
    STATUS    (*setup)(struct spi_controller *ctrl,
                       struct spi_device *dev);
    void       *priv;            /* 私有数据,指向硬件寄存器基址等 */
    /* ... 其他内部字段 */
} SPI_CONTROLLER;
数据结构 核心作用 关键字段
SPI_DEVICE 描述从设备硬件属性 chipSelect, mode, maxSpeedHz
SPI_MSG 封装一次传输请求 txBuf, rxBuf, len, csChange
SPI_CONTROLLER 管理 SPI 控制器硬件 transfer, setup, priv
SPI 核心数据结构关系 SPI_CONTROLLER transfer() setup() SPI_DEVICE chipSelect mode / maxSpeedHz SPI_MSG txBuf / rxBuf / len 包含 传输时传入 Controller 通过 transfer() 接收 Device + Msg
常见错误: 在初始化 SPI_DEVICE 时,如果未正确设置 maxSpeedHz 或 mode,控制器可能以错误的时序驱动总线,导致从设备无响应或数据错误。建议在驱动 probe 阶段打印配置参数进行验证。