中断上半部与中断下半部
中断上半部与中断下半部
第一部分:中断上半部与中断下半部是什么?
这是一个用于解决中断处理程序执行时间应尽可能短这一核心原则的设计模式。它把一个中断处理过程分为两个部分:
中断上半部 (Top Half) / 中断服务程序 (ISR)
角色: 紧急事务处理员。
工作内容:
执行最紧急、对时间极度敏感的操作。
典型的动作:读取外设状态寄存器以确认中断源、清除硬件中断标志、向硬件发送应答、将少量关键数据从硬件FIFO读取到内存中。
工作特点:
执行时间极短,几乎是微秒级的。
在所有中断被禁止的上下文环境中运行(即,它运行时会阻塞同级和更低优先级的中断)。
不能执行任何可能引起休眠或调度的操作(如获取互斥锁、等待信号量)。
中断下半部 (Bottom Half) / 延迟处理 (Deferred Processing)
角色: 不急但耗时的数据处理员。
工作内容:
执行不那么紧急但耗时的操作。
典型的动作:处理上半部读取到的数据(如解析网络数据包、处理音频帧、进行复杂计算)、通知等待数据的任务。
工作特点:
执行时间可以较长,毫秒级甚至更长。
在中断已启用的上下文环境中运行(即,它可以被更高优先级的中断抢占)。
可以执行更复杂的同步操作(如使用信号量、事件标志等与任务交互)。
一个经典的类比:
电话铃响了(中断发生)。
上半部:你立刻接起电话说“你好,请讲”(应答硬件,清除中断标志),然后说“稍等,我拿支笔”(将数据从硬件移到内存)。
下半部:你放下电话听筒(中断返回),然后开始处理电话内容,比如记录消息、查找信息、回复邮件(耗时处理)。在这个过程中,另一个电话可以打进来(中断可被抢占)。
第二部分:在Cortex-M3/M4的RTOS中,与中断延时的关系
首先,我们明确两个关键术语:
中断延迟 (Interrupt Latency): 从中断信号到达CPU到CPU开始执行该中断的第一条指令所经历的时间。这是硬件和RTOS调度器行为决定的时间。
中断处理时间 (Interrupt Processing Time): 执行整个中断服务程序(ISR) 所花费的时间。这是软件程序决定的时间。
现在,我们来分析它们之间的关系:
中断上半部与中断延迟的关系
上半部直接增加了中断处理时间,但不会直接影响中断延迟。
中断延迟是由关中断时间(中断屏蔽时间)、RTOS内核关键段长度(内核关键代码会禁用中断,也是中断屏蔽)、以及更高优先级ISR的执行时间决定的。一旦CPU开始执行你的ISR(上半部),中断延迟就已经结束了。
然而,一个冗长的上半部会严重损害系统的整体实时性。因为它会阻塞所有同级和更低优先级的中断。如果一个高优先级的中断被迫等待一个长的低优先级ISR执行完毕,那效果上就像是它的中断延迟变得非常长。
结论: 为了让其他紧急中断得到快速响应,必须将上半部做得极短,这间接减少了对其他中断的阻塞,相当于优化了它们的“感知延迟”。
中断下半部与中断延迟/实时性的关系
下半部机制的设计初衷就是为了减少上半部的执行时间,从而间接改善系统的中断响应和实时性。
在Cortex-M3/M4的RTOS中,下半部通常通过以下方式实现,它们与中断延时的关系如下:
下半部实现机制 | 工作原理 | 对中断延迟/实时性的影响 |
软件定时器回调 | 在上半部中启动一个单次执行的软件定时器,其回调函数作为下半部。 | 回调函数在定时器任务(优先级可控)中执行,不影响ISR退出。对中断无影响,实时性好。 |
守护任务 (Daemon Task) | 上半部将一个工作项(函数指针、数据指针)放入队列中。一个高优先级的专用任务阻塞在该队列上,一旦收到消息就执行下半部工作。 | 最佳方式之一。下半部在一个高优先级任务中运行,可以抢占普通任务,保证了实时性。不影响中断响应。 |
信号量/事件组 | 上半部释放一个信号量或设置事件位。一个或多个任务等待这个信号量/事件,被唤醒后执行下半部工作。 | 实时性取决于等待任务的优先级。如果任务优先级设得高,实时性就好。如果优先级低,则下半部可能被延迟。 |
PendSV (Cortex-M特有) | 上半部触发一个PendSV异常(优先级通常设为最低)。退出所有ISR后,PendSV handler作为下半部运行。 | 经典CMSIS-RTOS方式。PendSV是系统异常,用于上下文切换。它确保上半部快速完成,所有下半部工作在最低中断优先级进行,绝不会阻塞其他ISR,对中断延迟影响最小。 |
下图展示了基于守护任务(Daemon Task) 和 PendSV 这两种最常见的下半部处理流程,以及中断如何在其间发生:
总结
核心思想: 中断上半部要快。这是降低中断处理时间、避免阻塞其他中断、保证系统整体低延迟和高实时性的黄金法则。
关系:
中断延迟主要受RTOS关中断时间(即中断屏蔽时间)影响,与上半部的长度无直接关系。
上半部的长度直接决定了它阻塞其他中断的时间,这会严重影响其他中断的响应速度。
中断下半部机制将耗时的操作从上部分离,使得上半部变快,从而间接优化了系统的中断响应性能。
Cortex-M/RTOS实践:
利用Cortex-M的NVIC优先级和PendSV异常,可以优雅地实现下半部。
利用RTOS的队列、信号量、事件组和高优先级任务,是另一种非常灵活且有效的下半部实现方式。
因此,在基于Cortex-M的RTOS开发中,嵌入式工程师需要熟练运用上半部/下半部机制。