将少量数据从 ISR 上下文传递到任务/线程上下文

问题描述 投票:0回答:2

我对嵌入式软件世界有点陌生,我有一个设备,我在 RTOS 中为其编写了驱动程序,这样当它触发中断时,它的任务是从设备读取 32 位值并具有系统根据读取值中设置的位采取一些适当的操作。我想出的解决方案似乎有效,但我不确定它是否会因为效率低下而受到皱眉。

我意识到 ISR 本质上是破坏性的,因此为了在 ISR 上下文中花费尽可能少的时间,我将“适当的操作”逻辑分离到一个单独的线程中,以便它位于 ISR 上下文之外。

这是我采取的方法:

  1. 屏蔽设备中断。

  2. 从设备读取 32 位值。

  3. 使用消息队列发送值以在不同线程中进行处理。

  4. 清除并重新启用设备的中断。

这似乎工作正常,但我主要关心的是消息队列的使用。在 ISR 中使用消息队列的成本有多大,并且通常不受欢迎吗?有没有更好、更有效的方法将数据从 ISR 发送到不同的任务/线程?

embedded interrupt rtos
2个回答
0
投票

从中断写入消息队列是消息队列用途的典型案例。可以非常高效地完成。

我不确定你为什么要关闭中断。你的意思是在中断处理程序中关闭当前正在运行的中断?这对我能想到的任何架构都没有任何作用。 (如果我误解了这部分,也许可以编辑问题)。


0
投票

消息队列完全适用于由于突发写入或处理线程被更高优先级线程或中断抢占而导致新数据可能在旧数据处理之前到达的情况。

为了简单性和鲁棒性,它通常适用于总是在新数据到达之前处理数据的情况(RTOS 队列本质上是线程安全的)。但在这种情况下,您可能有一个包含单个消息的队列。

在第二种情况下,您可以简单地使用共享内存和线程信号原语,例如二进制信号量或事件标志。其“零拷贝”语义可以使其更加高效,但对于单个 32 位单词来说,这不太可能有意义。

如果数据是以流或突发形式到达的字序列,您可能会考虑的另一种技术是使用 DMA 传输。如果处理快速到达的数据流,这可以减少中断率和软件开销。在这种情况下,您可以使用队列或共享内存(DMA 缓冲区本身),但处理程序将是 DMA 中断,而不是设备中断。

我强烈建议您在中断处理程序中省略步骤 1 和 4。它应该是不必要的,并且可能会导致数据丢失。如果在处理程序中发生中断事件,它将处于挂起状态,ISR 将重新进入。在这种情况下,你肯定需要排队。这是不可能的,但在这种情况下,如果它们不会发生,也无需禁用它们。

© www.soinside.com 2019 - 2024. All rights reserved.