ISR vs main:运行 在一个或另一个中的权衡是什么?

ISR vs main: what are the trade offs of running in one or the other?

我知道这与时间和效率有关,以及 ISR 如何占用其他进程的时间,但我不清楚这是为什么。我总是被告知要保持 ISR 非常短。我有点困惑这是为什么。

通常,当硬件设备需要与 CPU 交互时,ISR 就会出现。他们发送一个中断信号,使 CPU 停止为中断服务所做的一切。这是 ISR 必须关心的。

现在,这取决于许多因素,硬件环境和中断的性质可能是最相关的因素,但通常情况下,为了正确处理中断,带有中断的 ISR 运行禁用,因此它们不能被打断。这意味着 CPU 在它是 运行 宁 ISR 代码时不能在其他进程之间共享,因为用于 运行 调度程序的系统定时器中断(它是内核的一部分负责制造 CPU 可以同时执行多项任务的错觉)将不起作用。

因此,如果您的 ISR 花费太多时间来执行设备的特定操作,您的系统将作为一个整体受到影响,因为 CPU 可用于其余进程的时间百分比会比平时少。这在带有 PIO 硬盘的旧系统上非常值得注意,它会中断 CPU 他们想要传输到 CPU 的每个磁盘扇区,并且 ISR 必须进行实际传输。如果磁盘流量很大,您可能会注意到鼠标移动时出现抖动(因为鼠标设备发送到 CPU 的中断未被处理)

OS像 Linux 这样的东西允许 ISR 将硬件设备的耗时操作推迟到 tasklet:一种可以与其他进程共享 CPU 时间的内核线程,同时保持硬件设备操作的原子性(OS 确保不会有超过一个 tasklet 函数 - 对于与 ISR 关联的特定 tasklet - 运行 同时在系统中)。从磁盘到内核缓冲区的 PIO 传输就是此类操作的一个示例。

通常,主线程的优先级低于ISR。根据调度程序,通常主要代码将在所有挂起的 ISR 已 运行 后执行。

在一个或多个 ISR 中使用大量计算密集型代码通常是不可取的,因为它可能会导致延迟甚至 CPU 低优先级 ISR 或线程的饥饿,如果时间关键代码,这可能是有害的需要执行。

但是,当需要在发生中断事件时立即采取措施时,最快的方法是从关联的 ISR 中执行代码(并可能为其分配高优先级)。

如果您计划使用多个执行耗时代码的中断源,方法是使用 RTOS 允许多个线程安全高效地交错以服务每个中断。

一些精度w.r.t。接受的答案。

当 运行 中断时,中断不一定被禁用,这不一定是内核在返回线程之前处理所有中断的原因。

有中断优先级的概念。更高优先级的中断将抢占 运行ning ISR:如果定时器中断的优先级高于 运行ning ISR,它将 运行.但是,此时内核不会处理上下文切换,而是将它们推迟到所有 queued/pending 个 ISR 都具有 运行.

此外,在某些处理器(例如 ARM Cortex-M3)上,处理中断的概念是处理器本身的一种操作模式。处理器在退出中断模式之前无法返回到 运行ning 线程。一旦发生这种情况,所有中断都会得到充分服务:您无法返回到 运行 中断 ISR。

但是所有 ISR 必须在返回线程之前完成的主要原因是内核没有 ISR 的类似线程的 运行ning 上下文的概念。因此,ISR 不能挂起 :它必须 运行 完成。因此,一个 ISR 占用了 CPU,除了更高优先级的中断,直到它完成它的目的。