发布网友 发布时间:4小时前
共1个回答
热心网友 时间:4小时前
软中断
软中断(Softirq)在Linux内核中是一种底半部处理机制,通常在顶半部返回时执行。软中断由softirq_action结构体表示,包含处理函数指针和参数。使用open_softirq()注册,raise_softirq()触发。软中断和tasklet运行于软中断上下文,属于原子上下文。工作队列运行于进程上下文,因此软中断和tasklet中禁止睡眠,而工作队列允许。
软中断执行的场景包括HI_SOFTIRQ、TIMER_SOFTIRQ、NET_TX_SOFTIRQ、NET_RX_SOFTIRQ、SCSI_SOFTIRQ、TASKLET_SOFTIRQ等。软中断与驱动编写无关,由内核自动管理。
软中断适度线程化,缓解高负载下的系统响应。内核会将大量软中断放入ksoftirqd线程执行。
硬中断、软中断、信号的区别:硬中断由外部设备触发,软中断是中断底半部处理机制,信号是内核或其他进程对进程的中断。软中断概念与通过软件指令引发的中断不同,后者与软中断不是一个概念。
threaded_irq
内核提供request_threaded_irq()和devm_request_threaded_irq()用于申请中断。这两个函数多了thread_fn参数,为中断号分配内核线程。中断上下文执行handler函数,内核线程执行thread_fn。如果handler结束时返回IRQ_WAKE_THREAD,内核调度thread_fn执行。支持IRQF_ONESHOT标记,自动屏蔽中断,避免中断服务程序退出后的中断洪泛。
handler参数可设为NULL,由内核使用默认处理函数和IRQF_ONESHOT标记。IRQF_ONESHOT在无法在上半部清除中断时特别有用。
GPIO按键中断
GPIO按键驱动通过request_any_context_irq()或devm_request_any_context_irq()申请中断,根据GPIO控制器的中断类型决定使用request_irq()或request_threaded_irq()。每个GPIO可能对应多个中断号,但共享一个中断控制器。
在GPIO按键驱动中,中断处理较为简单,不存在顶半部和底半部的明确划分。初始化时,通过INIT_WORK(&bdata->work,gpio_keys_gpio_work_func)初始化工作队列,用于处理按键事件。事件处理函数通过container_of()解析出对应的GPIO键数据结构。