处理多种中断源
考虑到各种传感器有 100 多种中断方式。所有这些也有可能同时发生。如何设计软件才能有效地处理它?
Consider that there are 100 plus ways of interrupts occuring from various sensors. There are chances that all can occur at the same time too. How can the software be designed to handle it efficiently ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这取决于您是否针对延迟或吞吐量进行优化。
既然您询问效率,我猜您正在考虑吞吐量。在这种情况下,一种经过验证的模式是让中断处理程序读取传感器、对命令和状态进行排队,然后立即返回。
您有一个不间断的软件线程从队列中选取命令并宣布处理程序的事件。这可以最大限度地减少任务切换时间。您可以使用特定于域的逻辑来组合命令、丢弃不再相关的命令等。
这本质上就是窗口系统的工作方式。每次鼠标单击、鼠标移动、键盘按下等都会导致命令排队。窗口系统挑选命令并调用相应的处理程序。有大量的逻辑用于丢弃在从队列中选取时不相关的命令、组合命令以及加速它们。
网络堆栈使用相同的模型。数据包按网络级别排队,然后主循环将它们挑选出来并使用控制模型反转来处理每个数据包。
It depends if you're optimizing for latency or throughput.
Since you asked about efficiency, I'll guess you're looking at throughput. In that case, one tried-and-true pattern is to have the interrupt handlers read the sensors, queue a command and state, and return immediately.
You have a non-interrupt software thread pick the commands off the queue and announce events for handlers. This minimizes your task switch time. You can use domain specific logic to combine commands, throw out commands that are no longer relevant, etc.
This is essentially how windowing systems work. Each mouse click, mouse movement, keyboard press, etc. results in a command being queued. The windowing system picks the commands off and calls a corresponding handler. There's extensive logic for throwing out commands that are not relevant by the time they are picked off the queue, for combining commands, and for expediting them.
Network stacks use the same model. Packets are queued by the network level, then a main loop picks them off and uses an inversion of control model to process each packet.
经验法则是,中断处理程序应该尽可能少地处理中断。让它们“尽可能短”。
例如,如果您的设备必须在串行端口上接收消息并对其做出响应:UART 串行 RX 中断处理程序应仅读取传入字节并将其存储在缓冲区中(并确保不存在缓冲区溢出)。就是这样。然后,主循环任务稍后应处理缓冲区中的数据,并在缓冲区中创建任何响应,以便可以通过串行 TX 中断处理程序传输它。
过去,我见过嵌入式软件,其中中断处理程序完成整个通信协议处理。它有效,但中断处理程序需要很长时间才能运行,因此延迟了其他中断处理程序的运行。这增加了其他中断处理程序无法及时处理其事件的风险。
The rule of thumb is that interrupt handlers should do as little as they possibly need to do to handle the interrupt. Keep them "as short as possible".
For example, if your device has to receive messages on a serial port and respond to them: The UART serial RX interrupt handler should just read the incoming byte and store it in a buffer (and ensuring there isn't a buffer overflow). That's it. Then a main loop task should later process the data in the buffer, and create any response in a buffer so it can be transmitted by a serial TX interrupt handler.
In the past, I've seen embedded software where the interrupt handler did the entire communication protocol handling. It worked, but the interrupt handler took a long time to run and so delayed other interrupt handlers from running. That increases the risk that other interrupt handlers do not process their event in time.
如果您的系统确实有数百个中断源,那么效率可能不是唯一的问题。您可能需要进行“拖延分析”,以确保在最坏的情况下不会满足要求。
首先,测量每个 ISR 的最坏情况时间。
然后,对于每个中断 X:
重新设计可以包括使 ISR 更快、调整 FIFO 长度、更改中断频率(减少收集更多数据的频率,反之亦然)、调整序列以保证某些中断不会同时发生。没有一种放之四海而皆准的策略。 (尽管更快的 ISR 几乎总是一件好事。)
If your system really does have 100s of interupt sources, efficiency may not be the only problem. You may have to do a "holdoff analysis" in order to make sure you aren't going to fail requirements in the worst case.
First, measure the worst case time for each ISR.
Then, for each interrupt X:
Redesign can include making the ISRs faster, adjusting FIFO lengths, changing the frequency of interrupts (gathering more data less often or vice versa), adjusting sequences so certain interrupts are guaranteed not to occur simultaneously. There is no one-size-fits all strategy. (although faster ISRs are almost always a good thing.)