凡亿教育-许媛
凡事用心,一起进步
打开APP
公司名片
凡亿课堂 | 面试指南
当前位置: 首页 面试指南
Linux中断怎么写?顶半部和底半部怎么分?嵌入式Linux面试
浏览量:432
2026-09-16 10:12:35
一句话答案

Linux 中断分 top-half(硬中断)和 bottom-half(软中断/tasklet/workqueue):硬中断里只做最紧急的事(读数据、清标志),耗时处理推迟到底半部;共享中断要用 IRQF_SHARED 并判断是否是自己的设备。

本文概述

中断是驱动开发核心,面试常考:request_irq、顶半部/底半部、tasklet/workqueue/线程化中断、共享中断。回答要讲清为什么要分两半。

核心要点

  • request_irq() 注册中断:传中断号、处理函数、flags、设备名、dev_id

  • 硬中断(top-half):关中断上下文,不能睡眠、不能调可能睡眠的函数

  • 底半部(bottom-half):软中断、tasklet(原子)、workqueue(可睡眠)

  • 中断里做最少:读数据、清标志;复杂处理放 workqueue

  • 共享中断用 IRQF_SHARED,处理函数通过 dev_id 判断是不是自己的中断

终端显示 Linux 中断处理代码,开发板用逻辑分析仪捕捉中断时序

面试官:Linux 驱动里中断为什么要分顶半部和底半部?

面试官考察点

面试官看你是否写过驱动中断、是否理解上下文。重点听:硬中断限制、为什么要分、三种底半部区别。

回答思路

先讲硬中断的限制,再讲为什么要分两半,最后讲三种底半部怎么选。

参考回答

为什么要分两半。硬中断运行时本地中断关闭(至少当前 CPU),这段时间越长,系统响应越慢。所以硬中断里只能做最紧急的事:

  • 读硬件数据(如 SPI 读 FIFO);

  • 清中断标志;

  • 告诉底半部有事件要处理。

复杂处理(协议解析、上报用户态)放底半部,不阻塞其他中断。

三种底半部对比。

机制上下文能否睡眠适用
软中断/ tasklet原子不能短、快、不睡眠
workqueue进程能耗时、要拿 mutex
线程化中断 threaded_irq进程能简单驱动,直接用线程

典型写法。

// 中断处理函数(硬中断)
static irqreturn_t my_irq_handler(int irq, void *dev_id) {
  struct my_dev *dev = dev_id;
  if (!my_irq_is_mine(dev)) return IRQ_NONE;
  my_clear_irq(dev);
  schedule_work(&dev->work); // 底半部
  return IRQ_HANDLED;
}

// 初始化
request_irq(irq_num, my_irq_handler, IRQF_TRIGGER_FALLING,
        "mydev", dev);
INIT_WORK(&dev->work, my_work_func);

硬中断里不能做什么。

  • 不能调用 copy_to_user(可能睡眠);

  • 不能拿 mutex(会睡眠);

  • 不能 printf(虽然 printk 不睡眠但耗时);

  • 不能做长循环或延时。

共享中断。多个设备共用一根中断线时,用 IRQF_SHARED 注册,处理函数要先读硬件状态寄存器判断是不是自己的设备触发的,不是就返回 IRQ_NONE。

面试官可能追问

追问 1:workqueue 和 tasklet 区别?
tasklet 在软中断上下文、原子、不能睡眠;workqueue 在内核线程、进程上下文、能睡眠。能睡眠的用 workqueue。
追问 2:中断为什么不能睡眠?
中断不在任何进程上下文,没有 task_struct 可以调度。一旦 schedule() 就会 oops。
追问 3:request_irq 的 dev_id 干嘛?
共享中断时用来区分设备;free_irq 时也要传同样的 dev_id。非共享传 NULL 也行。
追问 4:中断号怎么来?
设备树里配置 interrupts 属性,驱动 platform_get_irq() 取;GPIO 中断用 gpio_to_irq()。
追问 5:怎么调试中断没进来?
cat /proc/interrupts 看计数有没有涨;示波器量中断脚电平;确认触发方式(边沿/电平)对不对。

常见失分表达

✗ 中断里直接 copy_to_user — copy_to_user 可能睡眠,硬中断里会 oops。
✗ 中断里拿 mutex — mutex 会睡眠,硬中断上下文不行。
✗ 所有中断都用 tasklet — tasklet 原子,需要睡眠的处理必须用 workqueue。

准备动作

1
写一个字符设备驱动+中断+workqueue
2
cat /proc/interrupts 看系统中断统计
3
准备一个中断没进的排查案例
4
了解线程化中断(request_threaded_irq)

核心关键词

Linux中断request_irq顶半部底半部workqueuetasklet


声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。仅供学习交流使用,不构成商业目的。版权归原作者所有,如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时删除。 侵权投诉

相关文章

ADC采样电路前端设计怎么做?抗混叠滤波与驱动放大器选型全解析

2026-08-28 14:57:03

高速连接器与线缆的仿真建模怎么做?S参数提取与通道评估?PCB仿真面试

2026-09-12 15:38:34

电子工程师面试常见问题有哪些?技术面、HR面、谈薪怎么准备?面试技巧

2026-10-07 10:03:23

比较器电路怎么设计?迟滞阈值怎么计算?硬件工程师面试比较器应用

2026-08-22 14:01:41

天线驻波比突然升高:反射、馈线损耗和回波损耗怎么区分?

2026-10-25 11:06:00