为什么当内核当前处理中断时中断被禁用?
如果错过了带有重要信息的中断怎么办?
发布于 2015-09-27 21:29:24
这样可以防止“堆叠中断”导致内核堆栈溢出。它还可以防止死锁和/或“钉扎”。
大多数硬件不会“失去”一个中断。在中断期间,CPU的“中断标志”被清除,但是中断控制器--一个单独的猛兽--仍然可用/启用来记录新的中断。如果CPU正在处理hardware_A的中断(在“中断服务例程”ISR_A中),则仍然可以断言hardware_B的中断。它将被中断控制器记住,只是在那个时候它不会中断CPU。当ISR_A返回时,中断标志在退出时重新启用,现在将立即输入ISR_B (其调用堆栈帧将在与ISR_A相同的内存位置启动)。
虽然中断不会丢失/删除,但ISRs应该是短时间执行,以尽量减少延迟。换句话说,ISR_A不应该花费太长时间,以至于hardware_B在等待ISR服务时会溢出某些内部状态/缓冲区,因为它会继续积累数据。
最小化延迟是谨慎的内核设计和ISR设计的一部分。在Linux中,ISRs可以分解为ISR部分和“底部部分”或"tasklet“部分。中断禁用的ISR完成了设备服务/安静所需的最低限度(例如,清除设备中的一点,以防止它立即重新插入中断)。
然后,它启用了相应的任务线程,该任务在启用中断的情况下运行,以执行可能需要更长时间的更费力的操作。尽管名称是Tasklet,但它不像出现在"ps“中的完整任务/进程。它们是一种非常轻量级/高效的方法,可以分散ISR必须完成的工作,以减少延迟。
发布于 2016-03-01 19:30:24
我们来回答每一个问题。
内核当前处理中断时为什么禁用中断?
虽然有许多类型的中断,如I/O、计时器、看门狗、串行端口、外围设备和DMA,但让我们以I/O为例。我们将讨论一个原始案例并将其扩展到内核中。
想象一下,火灾报警/传感器位0/1连接到CPU的特定中断引脚。0是正常状态,1是火!然后将输入的中断配置为“级别触发”。一旦传感器触发1,ISR就必须执行相关代码,以发出警报或自动拨打消防部门的电话。当您进入ISR时,通常应该清除中断。如果它未被清除,硬件将继续中断CPU,ISR内部的安全代码将永远不会执行。
此外,CPU需要维护其当前执行状态的堆栈。反复出现的中断使它成为一个复杂的情况。
第二个例子是“边缘触发”或“转换触发”,假设输入行/引脚(NRZ编码)上出现了一系列位。如果ISR的工作是将这些比特组装成单词(8,16,32不管长度),我们需要清除中断,将该位组装成缓冲区,并在循环中再次启用中断。不清除中断将导致故障-y转换错误,只有1位为2位。
因此,实践是设置和启用中断,如果中断,清除它,执行ISR代码,并启用中断在任何相关的地方。
内核
内核本身是一段关键的代码,调度程序(也是OS定时器、OS时钟)依赖于硬件定时器中断。CPU中包含中断逻辑的硬件部分维护状态转换.它还具有启用、禁用、掩蔽和设置中断优先级的硬连接逻辑。
如果内核模块或潜水员模块应该安全地执行代码,则只有在执行处理程序之前禁用中断才能获得确定性行为。
如果错过了带有重要消息的中断怎么办?
中断处理不应该太长(在启用中断之前)。根据中断的频率和处理程序的复杂性,应该正确地设计代码。
https://stackoverflow.com/questions/32812704
复制相似问题