针对于嵌入式软件杂乱的知识点总结起来,提供给读者学习复习对下述内容的强化。
目录
4.linux中断的响应执行流程?中断的申请何时执行(何时执行中断处理函数)?
1.硬中断,软中断是什么?有什么区别?
硬中断:由硬件设备触发,响应时间要求非常快,通常用于紧急事件的处理。
软中断:由软件(操作系统)触发,通常用于延迟执行较为复杂的任务,响应时间不如硬中断紧急。
硬中断是由硬件设备触发的中断信号。硬件设备(如定时器、外设、I/O 设备等)在需要 CPU 处理时通过发送中断信号来打断 CPU 正常的指令执行流程。
工作原理
- 当外部硬件设备发生特定事件(如数据到达、硬件状态变化等),硬件会向 CPU 发出中断请求。
- CPU 在执行完当前指令后,会停止当前任务,跳转到相应的中断处理程序(ISR,Interrupt Service Routine)来处理中断请求。
- 中断服务程序(ISR)通常是高优先级的,必须尽可能短小快速地执行,避免占用过多的 CPU 时间。
- 一旦 ISR 执行完成,CPU 会返回到被中断的任务继续执行。
特性
- 由外部硬件触发,属于硬件事件。
- 通常是实时的,必须迅速响应硬件事件。
- 执行时,操作系统无法进行任务调度,因为 CPU 被打断并立即处理中断。
- 硬中断一般是不可预期的,必须确保中断处理的实时性。
常见的硬中断例子
- 外部传感器的数据变化
- 定时器中断
- 外部按钮或输入信号的变化
- 网络接口卡(NIC)数据接收中断
软中断是由软件程序触发的中断,不依赖硬件设备,而是由操作系统或应用程序通过软件指令触发,用来执行某些特定的操作。软中断机制用于延迟处理硬中断后的某些任务,或者用于执行一些高优先级的操作。
工作原理
- 软中断通常是在硬中断处理程序中通过内核代码触发的。在硬中断响应完成后,操作系统会通过软中断将一些较为复杂的任务推迟到稍后的合适时机执行。
- 软中断并不是立即执行的,它依赖操作系统的调度,通常是以工作队列 、定时器或其他机制的形式延迟执行。
- 软中断的处理通常发生在内核态,当硬中断处理程序完成后,软中断可能会被执行。
- 软中断的执行优先级通常低于硬中断,但比普通进程的优先级要高。
特性
- 由软件触发,通常是内核或操作系统中的事件。
- 用于延迟处理一些任务,或者处理高优先级的系统工作。
- 不需要硬件支持,完全由软件控制。
- 软中断可以在硬中断处理完成后执行,但不能打断硬中断本身。
常见的软中断例子
- 网络包的处理(网络协议栈的处理)
- 软中断用于管理定时器事件
- 内存管理相关的操作,如虚拟内存分页
- 调度任务(如 Linux 中的任务切换)
特性 | 硬中断(Hardware Interrupt) | 软中断(Software Interrupt) |
---|---|---|
触发源 | 外部硬件设备(如传感器、I/O设备、定时器等) | 由内核或操作系统软件触发 |
触发方式 | 硬件通过中断信号触发中断 | 通过软件指令或内核操作触发软中断 |
优先级 | 高,实时性要求强 | 低于硬中断,但通常比普通进程的优先级高 |
执行时间 | 中断处理程序通常需要快速执行,避免占用过多时间 | 软中断可以执行更复杂的操作,不需要立即响应,通常是延迟处理 |
响应时机 | 即时响应硬件事件,执行的任务非常紧急 | 在硬中断响应后执行,通常用于处理延迟的操作 |
控制方式 | 由硬件和 CPU 控制,通常不能被轻易禁止或改变 | 由操作系统控制,内核可以控制软中断的触发和执行 |
中断服务程序(ISR) | 由硬件中断触发的服务程序,通常必须尽可能短小和高效 | 由软件中断触发的服务程序,可能更复杂,处理时间更长 |
上下文切换 | 在硬中断处理期间,操作系统无法进行进程调度和上下文切换 | 软中断是在内核模式下执行,操作系统可进行上下文切换 |
中断嵌套 | 可以嵌套其他硬中断,但会受到优先级和硬件支持的限制 | 软中断通常无法直接嵌套硬中断,但可以在软中断中调用其他软中断 |
在嵌入式 Linux 中,硬中断和软中断常常是结合使用的。硬中断通常用来快速响应外部硬件事件,而软中断则用于推迟一些复杂的任务,以便在稍后的时间处理,避免阻塞实时的硬中断处理。例如:
- 硬中断:当外部设备(如网络接口卡)接收到数据时,它会触发硬中断,CPU 跳转到中断处理程序,快速处理中断。
- 软中断:硬中断处理完成后,操作系统可能会使用软中断来处理接收到的数据包(例如网络协议栈的处理),因为数据包的处理较为复杂,不能立即进行。
通过这种方式,系统能够保证实时的硬件事件响应,同时又能通过软中断来处理一些相对复杂但又重要的任务。
2.中断为什么要区分上半部和下半部?
Linux中断分为硬件中断和内部中断(异常),调用过程:外部中断产生->发送中断信号到中断控制器->通知处理器产生中断的中断号,让其进一步处理。
对于中断上半部和下半部的产生,为了中断处理过程中被新的中断打断,将中断处理一分为二,上半部登记新的中断,快速处理简单的任务,剩余复杂耗时的处理留给下半部处理,下半部处理过程中可以被中断,上半部处理时不可被中断。
-
上半部(Top Half):
- 上半部是中断的立即响应部分,通常在硬中断发生时会被调用。
- 处理程序在这部分应该尽量简短 、高效,避免长时间占用 CPU 和影响其他任务的执行。
- 上半部的主要任务是捕捉并记录中断源,执行一些必要的硬件操作,并尽快返回。它的目标是让中断的响应尽可能快,防止丢失重要的事件或数据。
-
下半部(Bottom Half):
- 下半部是中断的延迟处理部分,它通常在中断处理完毕后,在合适的时机(例如操作系统调度时)被执行。
- 这部分可以执行较为复杂的操作,如数据的处理、任务的调度等。与上半部不同,它可以使用系统调用和进程调度。
- 下半部的处理不需要立刻执行,因此可以延迟执行,以避免长时间占用中断上下文。
特性 | 上半部(Top Half) | 下半部(Bottom Half) |
---|---|---|
触发时机 | 由硬中断触发,立即响应硬件事件 | 在上半部处理完成后,由操作系统调度触发 |
执行环境 | 在中断上下文中执行,不能进行进程调度、内存分配等 | 在进程上下文中执行,允许进行内存分配、进程调度等复杂操作 |
执行任务 | 简单且高效的硬件相关处理,如记录中断源、清除中断标志等 | 复杂的任务处理,如数据处理、协议栈处理等 |
优先级 | 高优先级,实时性要求强 | 低于上半部优先级,通常需要在稍后的调度周期中处理 |
时间限制 | 必须尽量快速执行,以避免影响其他中断的响应和任务的执行 | 可以较长时间执行,不需要立即响应 |
任务内容 | 捕获硬件事件,清除中断标志,快速更新硬件状态,极少操作系统资源 | 数据的进一步处理、内存分配、进程调度、复杂算法等 |
中断嵌套 | 不能嵌套处理其他硬中断 | 可能会被其他软中断或工作队列触发 |
中断禁用 | 执行期间通常会禁用其他中断,防止中断嵌套 | 不需要禁用其他中断,允许并发执行 |
处理方式 | 硬中断处理程序(ISR),必须简短和高效 | 软中断或任务队列,允许较长时间的处理 |
处理方式的复杂度 | 较低,主要处理硬件相关的直接操作 | 较高,处理系统级的复杂任务,如内存分配、调度等 |
例子 | 网络中断接收数据、定时器中断、外设输入信号处理等 | 网络协议栈处理、内存管理、数据缓冲区清理等 |
3.中断下半部一般如何实现?
在嵌入式 Linux 中,中断的下半部 通常用于延迟执行较为复杂的任务,例如数据处理、协议栈处理或其他不适合在硬中断上下文中执行的操作。为了有效地实现下半部的处理,Linux 内核提供了几种常用的机制:软中断(Soft IRQ) 、任务队列(Tasklets) 和 工作队列(Work Queues)。这些机制可以让延迟的任务在合适的时机得到执行,从而不影响中断的实时性。想·
- 软中断(Soft IRQ)
软中断是 Linux 内核中的一种机制,旨在推迟某些中断相关的工作。它是在硬中断处理之后,由内核调度器根据优先级执行的。
使用场景:适用于需要在较高优先级下执行,但又不需要占用过多时间的任务,例如网络协议栈的处理、定时任务的更新等。
实现方式 :内核中定义了一些常用的软中断类型,例如网络处理(NET_RX
)、定时器处理(TIMER
)等。内核根据软中断的类型自动安排其执行。
特点:
软中断在内核上下文中执行,但可以并发执行。
由于软中断是由内核调度的,因此它的执行不需要立刻发生,而是可以推迟到合适的时机。
cpp
void my_softirq_handler(struct softirq_action *action)
{
// 处理一些延迟任务
}
void my_init_softirq(void)
{
open_softirq(MY_SOFTIRQ, my_softirq_handler);
}
- 任务队列(Tasklets)
任务队列是 Linux 中一种轻量级的软中断机制,用于处理比软中断更简单的延迟任务。它本质上是一个与中断相关联的延迟执行函数。
使用场景:适用于需要在中断上下文中执行的复杂任务,但这些任务的执行时间不能过长,且不依赖于系统调度。
实现方式:任务队列是由内核提供的一个高效的机制,用于在软中断上下文中延迟执行任务。
特点:
任务队列函数执行时,不会进行进程上下文的切换,且执行时不会阻塞其他任务。
它是单线程的,一个任务队列的任务执行期间,不会被其他任务打断。
任务队列是按优先级执行的,可以通过 tasklet_schedule()
和 tasklet_hi_schedule()
来调度任务。
cpp
static void my_tasklet_func(unsigned long data)
{
// 处理延迟任务
}
DECLARE_TASKLET(my_tasklet, my_tasklet_func, 0);
void my_interrupt_handler(int irq, void *dev_id)
{
// 在中断中调度任务
tasklet_schedule(&my_tasklet);
}
- 工作队列(Work Queues)
工作队列 是内核提供的机制,它允许在进程上下文中执行任务。工作队列比任务队列更灵活,可以执行复杂的任务,比如内存分配、文件系统操作或其他系统调用。
使用场景:适用于需要执行较长时间的任务,并且这些任务涉及到进程上下文的操作,例如内存分配、文件系统访问等。
实现方式 :工作队列可以将任务延迟到调度程序的上下文中执行,因此可以进行较复杂的操作。工作队列有两种形式:普通工作队列 和高优先级工作队列,后者通常用于需要快速响应的任务。
特点:
工作队列允许执行阻塞操作,因此适用于需要进程上下文的任务。
可以在进程上下文中执行,可以执行进程调度、内存分配等操作。
工作队列的调度是由内核调度器进行管理,支持多任务并发执行。
cpp
struct work_struct my_work;
void my_work_function(struct work_struct *work)
{
// 处理复杂任务
}
INIT_WORK(&my_work, my_work_function);
void my_interrupt_handler(int irq, void *dev_id)
{
// 在中断中调度工作队列
schedule_work(&my_work);
}
机制 | 描述 | 适用场景 | 特点 |
---|---|---|---|
软中断(Soft IRQ) | 在硬中断之后由内核调度执行,适用于中断后需要处理的简单任务。 | 网络协议处理、定时任务等 | 实时性较高,但任务较为简单,不涉及进程上下文。 |
任务队列(Tasklet) | 延迟执行的中断任务,用于硬中断后的延迟任务处理,具有优先级。 | 需要在中断上下文中执行的复杂任务,不能过长。 | 轻量级、中断上下文执行、任务队列具有较高优先级。 |
工作队列(Work Queue) | 延迟执行的任务,在进程上下文中执行,可以进行进程调度和阻塞操作。 | 复杂任务、涉及内存分配、文件系统操作等 | 支持阻塞操作、进程上下文、适合长时间运行的任务。 |
4.linux中断的响应执行流程?中断的申请何时执行(何时执行中断处理函数)?
中断的响应流程:cpu接受中断->保存中断上下文跳转到中断处理历程->执行中断上半部->执行中断下半部->恢复中断上下文。
中断的申请request irq的正确位置:应该是在第一次打开、硬件被告知终端之前。