1. 课程导论与工程背景
1.1 SPI总线在嵌入式系统中的核心地位
串行外设接口(Serial Peripheral Interface,SPI)是嵌入式系统中最广泛使用的高速同步串行通信协议之一。与I²C和UART相比,SPI以全双工、主从架构和极低协议开销著称,特别适合传感器、ADC/DAC、显示驱动、存储器等需要高数据吞吐量的外设连接。
SPI总线关键特性: 全双工通信、主从架构、无地址帧(通过片选线CS选择从设备)、时钟频率可达数十MHz、硬件流控简单。
下表对比了嵌入式系统中三大主流串行总线协议的核心差异:
| 特性 | SPI | I²C | UART |
|---|---|---|---|
| 通信模式 | 全双工 | 半双工 | 全双工 |
| 信号线数量 | 4(SCLK、MOSI、MISO、CS) | 2(SCL、SDA) | 2(TX、RX) |
| 从设备选择 | 独立片选线(硬件) | 7/10位地址(软件) | 点对点 |
| 最大时钟频率 | 典型10~80 MHz | 典型100 kHz~3.4 MHz | 典型115.2 kbps~数Mbps |
| 协议开销 | 极低 | 中等(ACK/NACK、地址帧) | 低(起始/停止位) |
| 多从设备支持 | 是(每设备独立CS) | 是(总线仲裁) | 否(需额外硬件) |
| 典型应用 | 传感器、ADC、LCD、Flash | EEPROM、温湿度传感器、RTC | GPS、蓝牙模块、调试串口 |
工程经验: 在需要连续高速数据流(如加速度计以10 kHz采样率输出三轴数据)的场景中,SPI是唯一能同时满足带宽和实时性要求的串行总线。I²C的时钟拉伸和ACK机制会引入不可预测的延迟。
下图展示了SPI总线在典型嵌入式系统中的连接拓扑:
1.2 传感器适配工程的核心挑战
在嵌入式Linux系统中,将物理传感器通过SPI总线接入内核并实现可靠的数据采集,远不止是“连接几根线、写一个驱动”那么简单。工程实践中,开发者面临以下系统性挑战:
- 硬件时序差异: 不同传感器厂商对SPI时钟极性(CPOL)、时钟相位(CPHA)、数据位序(MSB/LSB first)的要求各不相同,配置错误将导致数据完全错乱。
- 寄存器映射多样性: 每个传感器都有独特的寄存器地址空间、读写协议、多字节传输顺序(大端/小端)以及状态机控制流程。
- 中断与数据就绪信号: 传感器通常通过GPIO中断通知数据就绪,驱动需要协调SPI传输与中断处理,避免数据丢失或重复读取。
- 电源管理与功耗优化: 电池供电设备要求驱动在数据采集间隙将传感器置于低功耗模式,并通过SPI命令精确控制唤醒/休眠状态。
- 并发访问与数据一致性: 多个用户空间进程(如传感器融合算法、日志记录)可能同时访问同一传感器,驱动必须保证SPI传输的原子性和数据缓冲区的完整性。
- 内核态与用户态数据传递: 如何高效地将SPI采集的原始数据从内核驱动传递到用户空间应用程序,涉及字符设备、输入子系统、IIO子系统等多种架构选择。
常见陷阱: 许多初学者在编写SPI传感器驱动时,只关注“能读到数据”,而忽略了时序容差和错误恢复。当传感器在高温或电磁干扰环境下工作时,SPI传输可能发生位错误,驱动必须具备重试机制和错误校验能力,否则系统会出现随机数据跳变。
下表总结了传感器适配过程中不同层面的典型问题与应对策略:
| 层面 | 典型问题 | 工程应对策略 |
|---|---|---|
| 硬件接口 | SPI模式不匹配、电平不兼容 | 查阅数据手册确认CPOL/CPHA,使用电平转换器 |
| 寄存器协议 | 多字节顺序错误、保留位未处理 | 严格按手册实现读写函数,使用位域结构体 |
| 中断处理 | 中断丢失、数据竞争 | 使用自旋锁保护共享缓冲区,采用bottom half机制 |
| 电源管理 | 传感器持续耗电、唤醒延迟 | 实现suspend/resume回调,使用自动休眠定时器 |
| 数据路径 | 用户态读取延迟高、CPU占用大 | 采用IIO内核框架的triggered buffer模式 |
| 调试验证 | 无法确认SPI时序是否正确 | 使用逻辑分析仪抓取SCLK/MOSI/MISO波形 |
1.3 课程目标与学习路径
本课程旨在培养学员从零开始,在Linux内核中为SPI传感器编写高质量设备驱动的工程能力。课程覆盖从硬件协议分析、驱动框架选择、内核编程实现到用户空间验证的完整闭环。
课程核心目标:
- 掌握Linux SPI子系统架构(spi_master、spi_device、spi_driver)及核心API。
- 能够独立分析传感器数据手册,提取驱动开发所需的时序、寄存器、中断等关键信息。
- 熟练使用Linux内核的IIO(Industrial I/O)框架开发传感器驱动。
- 具备驱动调试、性能优化和电源管理工程实践能力。
下图展示了本课程30章内容的递进学习路径:
1.4 课程预备知识与工程环境
为获得最佳学习效果,学员应具备以下基础:
- C语言编程: 指针、内存管理、位运算、链表操作。
- Linux基础: 文件系统、进程管理、命令行操作。
- 嵌入式基础: GPIO、中断、时钟树的基本概念。
- 硬件基础: 能够阅读芯片数据手册的时序图和寄存器表。
推荐实验环境:
- 主机:Ubuntu 22.04 LTS 或更新版本
- 交叉编译工具链:arm-linux-gnueabihf- 或 aarch64-linux-gnu-
- 目标板:Raspberry Pi 3/4 或 BeagleBone Black(均内置SPI控制器)
- 逻辑分析仪:Saleae Logic 8 或兼容设备(用于SPI时序验证)
- 传感器模块:ADXL345(加速度计)、MPU9250(九轴)、BME280(环境)
本课程所有驱动代码均基于Linux内核版本 6.1 LTS 进行开发和测试,该版本具有长期支持且SPI/IIO子系统接口稳定。学员可在此基础上适配其他内核版本。