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 模式。模式不匹配会导致通信数据错位或完全失败。
1.2 VxWorks SPI 框架层次
VxWorks 的 SPI 驱动框架采用分层设计,从底层硬件到上层应用分为四个层次:
- 硬件层(Hardware Layer):SPI 控制器寄存器操作、时钟配置、GPIO 片选控制。
- 总线驱动层(Bus Driver Layer):实现 SPI 控制器初始化、数据传输、中断处理,向上提供标准接口。
- 核心层(Core Layer):VxWorks 提供的 SPI 核心框架,管理设备注册、消息队列、传输调度。
- 从设备驱动层(Slave Device Driver Layer):针对具体 SPI 从设备(如 Flash、传感器)实现的驱动,调用核心层 API 完成通信。
架构要点: 从设备驱动层不直接操作硬件寄存器,而是通过核心层提供的 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_DEVICE 时,如果未正确设置 maxSpeedHz 或 mode,控制器可能以错误的时序驱动总线,导致从设备无响应或数据错误。建议在驱动 probe 阶段打印配置参数进行验证。