前言
一、
在与RT-Thread BSP的开发者沟通中,发现SPI设备驱动在轮询(Polling)模式下偶发出现非法访问异常(如图)

问题复现场景:
开发者仅需一次单消息传输,但未显式初始化struct rt_spi_message的next指针。
由于next未赋值为RT_NULL,链式传输时触发非法内存访问(next指向不可控地址)。
修复方案 :将next显式置空后,异常消失。
借此机会,本文将深入解析RT-Thread SPI驱动的链式传输机制,并探讨BSP对RT-Thread SPI接口的适配特点与优势。
RT-Thread SPI链式传输机制解析
二、
1.核心数据结构:struct rt_spi_message
RT-Thread通过struct rt_spi_message描述SPI传输操作,支持单条或多条消息链式传输。
关键成员next
1)若为NULL,表示当前为链式传输的最后一条消息。
2)若非NULL,需确保next指向的rt_spi_message已正确初始化。
3)未初始化next的后果链式传输时,驱动会尝试访问next指向的无效地址,导致非法访问异常。
在RT-Thread的官方wiki示例可以看到,在定义一个spi message时,需要操作next成员以便确认是否有下一条链式传输。如果没有需要赋值为NULL。在RT-Thread的wiki可以看到,在使用rt_spi_transfer_message 传输两条msg,在第二条msg的next赋值为RT_NULL代表结束。
在RT-Thread组件SPI相关也对next进行了操作,并且做了相关注释说明
先楫BSP适配
三、
那么可能就有开发者问了,为什么别的BSP SPI驱动反而就没事了,可以在RT-Thread的主线看到,多数厂商(如STM32)的SPI驱动未处理next指针,仅支持单条消息传输,但链式传输时易因next未处理导致传输异常。
而先楫BSP的SPI驱动严格按照RT-Thread规范实现链式传输逻辑,强制校验next指针。支持单条/链式传输,兼容复杂场景。
先楫BSP对DSPI和QSPI的支持
四、
不同与其他厂家的BSP,把SPI和QSPI分开两个驱动文件,先楫是集成在SPI驱动中,因为先楫SPI本身就是一个外设,可以支持SPI,DSPI,QSPI三种传输模式。
怎么开启这三种模式,可以通过menuconfig进入到对应的界面进行选择:分别是单线SPI,两线DSPI,四线QSPI。
如果想在RT-Thread Studio操作,可以参考下图:
需要注意的是:当使用四线QSPI时,对应的pinmu.c的SPI初始化需要加上QSPI的D2和D3初始化。
通过list device命令可看到:SPI0为单线SPI,SPI1为双线DSPI,SPI2为四线QSPI
总结
五、
链式传输陷阱:未初始化next指针是SPI驱动异常的常见原因,开发者需严格遵循RT-Thread规范。
先楫BSP优势
1. 严格适配RT-Thread链式传输逻辑,避免非法访问。2. 集成SPI/DSPI/QSPI驱动,简化开发流程。