本问题的相关参数如下:
1。IDE:适用于 ARM v 2.2 的 S32 DS(是的,我知道这个已经过时了,但是有问题的产品也是;我们需要支持现有代码)
2.芯片:S32K148
3.操作系统视窗 11
4.系统操作系统:裸机
在 ISR 中尝试执行任何类型的 SPI 主传输都会挂起,通常被中断的 API 是阻塞 I/O(I2C 或 SPI)调用。
在阻塞调用(调用 LPSPI_DRV_MasterTransferBlocking())中,通话挂起是因为 SysTick 中断似乎没有发生,因此 MCU 无法感知时间流逝。
在非阻塞调用(LPSPI_DRV_MasterTransfer(),然后是 LPSPI_DRV_MasterGetTransferStatus(SPI1,&byte_remaining))中,byte_remaining 保持原值。我尝试在调用 LPSPI_DRV_MasterAbortTransfer() 进行异步传输之前,添加对 LPSPI_DRV_MasterAbortTransfer(SPI1) 的调用,但结果还是一样。
关于一个半相关的问题,是什么触发了 SysTick_Handler()?我的直觉告诉我,它应该一直运行,每 1 毫秒增加一次刻度计数,但在其正文中设置一个断点似乎只能在某些时间触发。奇怪的是,即使阻塞性 SPI 传输成功,有时也不会触发,如果系统定时器之前未触发,则应触发系统定时器。
另一个半相关的问题是,在 SPI 的 S32 Cookbook 示例代码中,没有使用 SDK 提供的应用程序接口;这些示例直接完成了所有寄存器位操作。是否有更接近生产价值代码的示例,因为它们至少调用了恩智浦的应用程序接口,而不是重新发明轮子?
你好@PetrS
非常感谢。中断优先级确实解决了这个问题。不过,我有一个问题:
我同意在 ISR 中阻塞不是一个好主意,但在单线程应用程序中又有什么办法呢?我可以在应用程序上下文中旋转,直到 SPI 传输完成。这将允许其他 I/O 中断发生(我的理解是,负优先级中断无论如何都会触发;当进入正优先级 ISR 时,它们不会被禁用)。但是在我的情况下,进行重叠的 I/O 既不可能,也不可取。
1.这是不可能的,因为 S32K148 是所有总线的总线主控器。因此,如果它在 ISR 中进行 SPI 传输,则可能无法驱动另一条 I/O 总线,因此无法触发中断。
2.这并不可取,因为 ISR 之间可能存在共享全局,所以我不想在当前 I/O 完成之前启动新的 I/O。
对于单线程裸机应用程序,您建议如何处理这种情况?
您好,
好吧,那么只需中断优先级就能导致这种行为。阻塞 API 会挂起的原因很简单,如果两个中断具有相同的优先级,那么当 GPIO ISR 处于活动状态时,LPSPI ISR 就无法运行。阻塞调用等待 ISR 完成传输并发布信号,但在 GPIO ISR 退出之前,ISR 永远不会获得 CPU 时间。SDK 的驱动程序确实在 LPSPI 中断中完成传输,然后才发布信号量以释放屏蔽调用,因此同等优先级 ISR 将以这种方式使传输陷入僵局。
非阻塞 API 的行为相同:如果从具有相同优先级的 GPIO ISR 调用,LPSPI ISR 无法抢占它的优先级,因此 byte_remaining 永远不会改变,因为驱动程序状态机永远不会被 LPSPI IRQ 服务。只有将 LPSPI 提高到更高优先级(数值较低)后,LPSPI 中断才会立即触发,完成传输,并允许阻塞和非阻塞 API 按预期工作。尝试
您好,
您好,
仅将 ISR 用作触发信号;在 main () 中同步执行 SPI 传输,或者在 ISR 中启动但由 LPSPI ISR 完成的非阻塞传输,主等待完成标志。
BR, Petr