0

我正在尝试对 stm32 进行编程并使用事件驱动架构。例如,当发生定时器中断时,我将切换一个引脚,并在发生 ADC DMA 缓冲区满中断时将一些数据传输到外部闪存等等。

将有多个中断源,每个中断源具有相同的优先级,从而禁用嵌套。

我将使用中断来设置一个标志来通知我的 main 发生了中断并在 main 中处理数据。ISR 内部不会有处理/指令。

困扰我的是,从长远来看,在 main 和 ISR 中访问变量(在这种情况下为标志)可能会导致竞争条件错误。

所以我想使用循环事件队列而不是标志。

只有 ISR 能够写入事件队列缓冲区并增加“head”。只有 main 能够读取事件队列(并根据事件执行指令)并增加“tail”。

由于 ISR 嵌套被禁用,并且每个 ISR 将访问事件队列数组的不同元素,并且主函数只会在事件队列上有新事件时做出反应,所以避免了竞争条件对吗?还是我错过了什么?

如果我做错了什么,请纠正我。

谢谢你。

4

1 回答 1

0

如果中断只设置了一个变量,并且在主上下文准备好之前什么都不做,那么根本就没有理由产生中断。

例如:如果你得到一个 DMA 完整的硬件中断并设置了一个变量,那么你所做的就是将一位信息从硬件寄存器复制到一个变量中。通过轮询变量而不是不启用中断并直接轮询硬件标志,您可以拥有更简单的代码,具有相同的性能和更少的错误可能性。

仅当您实际上要在无法等待的中断上下文中执行某些操作时才启用中断,例如:读取 UART 接收到的数据寄存器,以便接收到的下一个字符不会溢出缓冲区。

如果在中断完成后不能等待的事情然后需要与主上下文进行通信,那么您需要共享数据。这意味着您需要某种方法来防止竞争条件。最简单的方法是原子访问,只有一侧写入数据项。如果这还不够,那么老式的方法是在主上下文访问共享数据时关闭中断。使用 LDREX/STREX 指令有更复杂的方法,但只有在确定简单方法对您的应用程序不够好时,您才应该探索这些方法。

于 2021-03-25T13:59:54.953 回答