【Linux驱动开发】第21天:SPI总线协议与SPI子系统基础理解

发布时间:2026/6/29 19:44:33
【Linux驱动开发】第21天:SPI总线协议与SPI子系统基础理解 一、SPI总线协议基础1. 硬件结构4线制同步串行总线SPISerial Peripheral Interface串行外设接口是一种全双工、同步、主从架构的串行总线标准模式下需要4根信号线比I2C多2根但通信能力更强。信号线全称方向作用SCLKSerial Clock主→从串行时钟由主设备产生控制通信节奏MOSIMaster Out, Slave In主→从主设备发、从设备收的数据线MISOMaster In, Slave Out从→主从设备发、主设备收的数据线CS/SSChip Select / Slave Select主→从片选信号低电平有效每个从设备独占一根选中哪个哪个才工作核心特点单主多从一条SPI总线上只能有1个主设备可以挂多个从设备靠独立的CS线区分从设备没有I2C那样的“从设备地址”概念。全双工通信两根独立数据线发送和接收可以同时进行而I2C只有一根数据线是半双工同一时间只能单向传输。同步通信所有数据都跟着SCLK时钟走主设备控制时钟频率从设备被动跟随不需要各自的时钟源。2. 主从模式通信原理SPI通信的本质是移位寄存器的同步移位主设备和从设备各有一个移位寄存器SCLK每跳变一次两边同时移出1位数据到对方的寄存器里。一个完整的字节传输过程主设备拉低对应从设备的CS线选中该从设备主设备产生SCLK时钟按照设定的频率和极性跳变每个时钟周期主设备通过MOSI发出1位数据同时从MISO采样1位数据从设备通过MISO发出1位数据同时从MOSI采样1位数据8个时钟周期后双方完成1个字节的交换主设备拉高CS线结束本次通信通俗理解SPI通信就像两个人面对面同时交换纸条你写一个字给我的同时我也写一个字给你节拍由其中一个人主设备统一打拍子控制。3. 四种工作模式CPOL CPHASPI通过两个参数配置时序组合成4种标准模式不同外设可能要求不同模式驱动必须和外设匹配。参数全称含义CPOLClock Polarity时钟极性SCLK空闲时的电平。0空闲低1空闲高CPHAClock Phase时钟相位在第几个时钟边沿采样数据。0第一个边沿1第二个边沿模式0最常用CPOL0CPHA0 → 空闲时钟低第一个上升沿采样数据模式1CPOL0CPHA1 → 空闲时钟低第一个下降沿采样数据模式2CPOL1CPHA0 → 空闲时钟高第一个下降沿采样数据模式3次常用CPOL1CPHA1 → 空闲时钟高第一个上升沿采样数据二、Linux SPI子系统架构和I2C完全对应Linux SPI子系统也是经典的三层架构思路和I2C高度一致只是结构体和API名称不同。┌─────────────────────────────────┐ │ SPI设备驱动层spi_driver │ │ 外设业务逻辑Flash、屏、ADC等 │ ├─────────────────────────────────┤ │ SPI核心层spi-core │ │ 通用API、设备管理、驱动匹配 │ ├─────────────────────────────────┤ │ SPI控制器驱动层spi_master │ │ 硬件控制器操作RK3399 SPI驱动 │ └─────────────────────────────────┘1. 第一层SPI控制器驱动层定位最底层直接操作SoC内置的SPI控制器硬件核心结构体struct spi_master代表一个SPI控制器主机包含控制器的硬件信息、时钟、中断、DMA等资源核心职责初始化SPI控制器硬件时钟、引脚、中断、DMA配置SPI模式、时钟频率、位宽等参数实现数据传输接口向上层提供统一的传输能力RK3399对应源码drivers/spi/spi-rockchip.c2. 第二层SPI核心层定位中间桥梁对上下提供统一接口隔离硬件和业务核心源码drivers/spi/spi.c核心职责提供spi_master的注册/注销API提供SPI设备驱动的注册/注销API实现设备树匹配、设备-驱动绑定机制封装通用传输逻辑消息队列、同步/异步处理提供通用API供设备驱动调用屏蔽硬件差异对开发者的意义写SPI外设驱动时只需要调用核心层API完全不用关心底层是RK3399还是其他平台的控制器。3. 第三层SPI设备驱动层定位最上层实现具体外设的业务逻辑核心结构体struct spi_device代表一个SPI从设备包含片选号、模式、时钟频率、所属控制器等信息struct spi_driver代表一个SPI设备驱动包含probe、remove、匹配表等常见外设W25Q系列SPI Flash、OLED/LCD显示屏、ADC芯片、以太网网卡、CAN控制器等开发方式注册spi_driver通过核心层提供的传输API和外设通信。三、SPI核心传输机制1. 两个核心传输结构体SPI用两层结构描述一次传输结构体作用struct spi_transfer单次传输单元描述一段连续的收发数据struct spi_message一次完整的SPI事务由一个或多个spi_transfer组成特点一个spi_message中的所有传输共用同一个CS片选状态CS全程保持低电平每个spi_transfer可以单独配置长度、速度、位宽等传输完成后CS才会拉高结束本次事务2. 两种传输方式1同步传输spi_sync阻塞等待传输完成函数返回时数据已经收发完毕用法简单适合大多数场景原型int spi_sync(struct spi_device *spi, struct spi_message *message)2异步传输spi_async非阻塞函数立即返回传输完成后通过回调函数通知适合高并发、大流量场景原型int spi_async(struct spi_device *spi, struct spi_message *message)3. 便捷封装API为了简化使用核心层封装了常用的单字节、多字节读写函数spi_write()写数据spi_read()读数据spi_write_then_read()先写后读最常用比如写寄存器地址再读数据四、I2C vs SPI 全方位对比1. 核心参数对比表维度I2CSPI信号线数量2根SCLSDA标准4根SCLKMOSIMISOCS多从设备需额外CS线寻址方式7/10位软件地址所有设备共用总线硬件片选线每个从设备独占一根CS通信方式半双工同一时间只能单向传输全双工收发同时进行同步方式同步主设备控时钟同步主设备控时钟典型速率标准100Kbps快速400Kbps高速3.4Mbps几十Mbps很常见高端可到上百Mbps从设备数量理论最多127个7位地址受总线电容限制受CS引脚数量限制一般几个到十几个协议复杂度有起始/停止、ACK应答、仲裁机制协议复杂无固定帧格式无应答无仲裁协议简单硬件成本低只需2根线支持多设备级联高每个从设备多一根CS线引脚占用多抗干扰性一般开漏输出需上拉电阻较好推挽输出驱动能力强多主支持支持多主机有总线仲裁标准SPI不支持多主机2. 使用场景差异优先选I2C的场景低速传感器类外设温湿度、加速度计、陀螺仪、光感等数据量小对速率要求不高板级配置类芯片RTC时钟、EEPROM、IO扩展芯片、PMIC电源管理芯片引脚资源紧张MCU/SoC引脚不足希望用最少的线挂多个设备多设备级联同一条总线上挂十几个低速设备不需要额外引脚需要多主机系统中有多个主控需要访问同一个外设优先选SPI的场景高速大数据量传输SPI Flash、LCD/OLED显示屏、摄像头、以太网网卡需要频繁传输大量数据高性能外设高速ADC/DAC、FPGA通信对速率和延迟要求高全双工通信需要同时收发数据的场景比如某些工业通信芯片协议简单灵活外设没有标准I2C接口自定义SPI协议更灵活对时序要求严格SPI时钟稳定延迟更低时序更可控五、SPI设备树的核心特点I2C vs SPI 设备树reg对比总线reg属性含义示例I2C7位从设备物理地址reg 0x50;// 地址0x50SPI片选通道号第几个CSreg 0;// 使用第0个片选RK3399 SPI从设备节点示例spi1 { status okay; pinctrl-names default; pinctrl-0 spi1_clk spi1_mosi spi1_miso spi1_cs0; flash0 { compatible winbond,w25q128; reg 0; // 使用SPI1的第0个片选 spi-max-frequency 50000000; // 最大时钟50MHz spi-cpol; // CPOL1 spi-cpha; // CPHA1 → 模式3 status okay; }; };