异步接口的调用返回与事务完成分开。缓冲区何时能修改或释放,要依据对应版本的完成通知、结果与驱动访问范围判断。
异步SPI调用返回,程序可以继续执行,但这不表示驱动已经用完发送缓冲区。若下一次操作立即覆盖同一块内存,仍在进行的事务可能读到变化后的数据。应把"调用被接受"和"事务完成"分开管理。
返回值与完成通知各管一段
Zephyr本次打开的SPI文档说明,异步传输通过回调或信号机制报告完成。spi_transceive_cb还说明:回调为NULL时,不会通过该回调通知事务结束及其成功与否。
因此,程序既要处理调用阶段的错误,也要处理后续完成结果。仅打印一条"发送调用成功",不足以交代这次总线事务的全部状态。文档还提示,总线忙时异步调用本身也可能等待,不能把异步简单理解成绝不阻塞。
把缓冲区的归属写清楚
在驱动仍可能访问期间,不要修改、释放或把同一内存交给另一事务。栈上临时数组、被复用的通信工作区及多任务共用缓冲区,都应明确何时开始由谁使用、何时归还。
可在项目中建立"空闲、传输中、完成待处理"的归属记录,并让状态变化与实际通知对应。这是协作设计建议;具体缓冲区、配置结构的有效期和线程约束,还应核对项目所用Zephyr版本及驱动。
异常路径也要收尾
如果完成结果是错误,不能只把缓冲区标为可用而丢掉错误信息;若等待超时,也不能凭等待结束就认定硬件访问已经终止。应按对应接口设计取消或恢复流程,再确定何时安全归还资源。
本文依据的latest接口页显示4.5.0-rc3,不能代替项目锁定版本的文档。排查采购硬件与驱动协作问题时,可在活库需求清单注明完整器件型号及实际开发环境。
FAQ
回调为NULL,可以把函数返回当完成通知吗?
不能据此推断。所引接口明确说明NULL回调不会通知事务结束及成功与否,应选择项目可核实的完成机制。
等待超时后,发送内存就一定能立即释放吗?
不一定。超时是等待方的状态,还需确认驱动或硬件是否仍在访问,再按实际接口完成收尾。