1

In my firmware I write to MicroSD in a background task, and I've got a lot of higher-priorities interrupts enabled, some of which can take several milliseconds.

So the writing/reading from SPI can be interrupted at any moment, and for writes that may not be such a problem (if SPI behaves anything like UART), but during reads I'm afraid that my hardware SPI FIFO's will overflow if the task just happens to be interupted while the MicroSD card is sending a datablock.

Now the obvious solution would be to decrease the time that the higher priority interrupts take, but this seems very hard, because sometimes they have to wait on other peripherals too, and too prevent that I have to rewrite a lot of code that does polling now, to an interrupt-structure, which would make the overall code much more complicated.

I think in modern OSes this is solved by letting all those tasks run synchronously at the same priority, and give them all an equal time slice. But I don't have any mechanisms for threading, or an OS, so what would be the simplest way to solve this?

4

2 回答 2

4

写入 MicroSD [...] 硬件 SPI FIFO 将溢出

是 SPI 的主人:您控制 SPI 时钟。SPI Master 只有在有数据帧要传输时才会产生时钟信号——否则时钟处于空闲状态。对于读操作也是如此:SPI 总是同时读取和写入。

总之,如果你是主人,SPI永远不会溢出。硬件 FIFO 不会改变这一事实。

于 2013-02-02T17:47:07.840 回答
0

“我认为在现代操作系统中,这是通过让所有这些任务以相同的优先级同步运行并给它们一个相同的时间片来解决的。但我没有任何线程机制或操作系统,所以会是什么?解决这个问题的最简单方法?”

操作系统中的多任务处理与中断不同。

我会布局以下内容:

用于读取和写入的 SPI 中断处理程序。您已经获得了需要注意的 SPI FIFO。您可能会因溢出和“水印”情况而中断。一定要处理好这些。阅读您的 MCU 用户指南了解详情。在软件中为您的中断处理程序提供自己的循环队列。给定 FIFO 的大小,适当调整队列的大小(这是基于硬件 FIFO 大小、您正在读取/写入的设备的页面大小和可用内存的选择。)

要从您的应用程序调用的状态机模块。这应该有自己的循环队列。状态机应该具有读取和写入数据的功能,以及“泵”功能(即从主循环定期调用的功能,也就是从主循环“调度”的功能)。

从 SPI 设备状态机读取和写入的“任务”也应该是状态机,它们还应该能够处理无法写入或没有数据准备好的情况。一般来说,不要阻塞!编写你的函数,以便如果他们需要的东西没有准备好/可用,他们就会退出,期待被调用,也就是稍后的“计划”。

所以一般流程是:

【要写的任务】->队列->【设备状态机】->队列->【SPI中断】->硬件队列->【硬件】->连线

线 -> [硬件 -> 硬件队列 -> [SPI 中断] -> 队列 -> [设备状态机] -> 队列 -> [要读取的任务]

如果没有关于您的架构的细节,很难提供更多细节。但是我已经在许多嵌入式设备驱动程序中成功地使用了这种模式。

于 2013-02-02T18:02:07.773 回答