当前位置: 首页 > news >正文

[Linux外设驱动详解]6. 中断处理

6. 中断处理

概述

中断是硬件与操作系统内核通信的核心机制。当硬件设备需要 CPU 注意时,会通过中断信号线向 CPU 发送请求。Linux 内核采用分阶段处理策略来响应中断:

  • 上半部(Hard IRQ):在硬件中断上下文中执行,快速响应,禁止抢占
  • 下半部:在稍后执行,处理耗时操作,允许睡眠

中断请求

快速处理

触发下半部

硬件设备

CPU

上半部
Hard IRQ

中断控制器

下半部机制

软中断

Tasklet

工作队列


6.1 上半部 vs 下半部

6.1.1 为什么需要分阶段处理?

特性上半部下半部
执行上下文硬件中断上下文软中断/进程上下文
禁止抢占
允许睡眠部分允许(仅工作队列)
执行时间尽可能短可较长
响应速度最快稍慢

设计原则

  • 上半部只做必须立即完成的事情:读硬件寄存器、应答中断
  • 下半部处理耗时操作:数据处理、拷贝、与设备协议交互

6.1.2 软中断(Softirq)

软中断是下半部的基础机制,在内核编译时静态定义。软中断类型在 include/linux/interrupt.h:532-546 定义:

enum{HI_SOFTIRQ=0,// 高优先级软中断TIMER_SOFTIRQ,// 定时器软中断NET_TX_SOFTIRQ,// 网络发送软中断NET_RX_SOFTIRQ,// 网络接收软中断BLOCK_SOFTIRQ,// 块设备软中断IRQ_POLL_SOFTIRQ,// IRQ轮询软中断TASKLET_SOFTIRQ,// Tasklet软中断SCHED_SOFTIRQ,// 调度软中断HRTIMER_SOFTIRQ,// 高精度定时器软中断RCU_SOFTIRQ,// RCU软中断NR_SOFTIRQS};
软中断数据结构

每个 CPU 维护一个软中断向量表 include/linux/interrupt.h:565-568:

structsoftirq_action{void(*action)(structsoftirq_action*);};
软中断执行流程

核心处理函数在 kernel/softirq.c:260:

asmlinkage __visiblevoid__softirq_entry__do_softirq(void){structsoftirq_action*h;__u32 pending;pending=local_softirq_pending();// 获取待处理软中断位图h=softirq_vec;while((softirq_bit=ffs(pending))){h+=softirq_bit-1;h->action(h);// 调用软中断处理函数pending>>=softirq_bit;}}

执行时机

  1. 上半部退出时(如果in_interrupt()为 false)
  2. ksoftirqd内核线程被唤醒时
  3. 明确调用do_softirq()
软中断注册
// kernel/softirq.c:654-655open_softirq(TASKLET_SOFTIRQ,tasklet_action);open_softirq(HI_SOFTIRQ,tasklet_hi_action);

6.1.3 Tasklet

Tasklet 是基于软中断的动态下半部机制,主要特点:

  • 同一个 Tasklet同一时刻只能在一个 CPU 上运行
  • 不同 Tasklet可以并行在不同 CPU 上运行
  • 不能睡眠
Tasklet 数据结构

定义在 include/linux/interrupt.h:620-631:

structtasklet_struct{structtasklet_struct*next;// 链表下一节点unsignedlongstate;// 状态(0/TASKLET_STATE_SCHED)atomic_tcount;// 引用计数(0=使能,非0=禁用)bool use_callback;// 是否使用新式callback APIunion{void(*func)(unsignedlongdata);// 旧式处理函数void(*callback)(structtasklet_struct*t);// 新式处理函数};unsignedlongdata;};
Tasklet 使用示例
// 定义和初始化DECLARE_TASKLET(my_tasklet,my_tasklet_handler);// 或者动态初始化structtasklet_structmy_tasklet;tasklet_setup(my_tasklet,my_tasklet_callback);// 调度 Tasklettasklet_schedule(&my_tasklet);// 处理函数voidmy_tasklet_callback(structtasklet_struct*t){// 这里不能睡眠printk("Tasklet running on CPU %d\n",smp_processor_id());}
Tasklet 执行流程

kernel/softirq.c:548-592:

staticvoidtasklet_action_common(structsoftirq_action*a,structtasklet_head*tl_head,unsignedintsoftirq_nr){structtasklet_struct*list;// 取出所有待处理的 taskletlist=tl_head->head;tl_head->head=NULL;while(list){structtasklet_struct*t=list;list=list->next;if(tasklet_trylock(t)){// 尝试获取锁(防止多CPU并发)if(!atomic_read(&t->count)){// 检查是否被禁用t->callback(t);// 执行 tasklettasklet_unlock(t);continue;}tasklet_unlock(t);}// 如果正在其他CPU运行,重新调度t->next=NULL;*tl_head->tail=t;__raise_softirq_irqoff(softirq_nr);}}

6.1.4 工作队列(Workqueue)

工作队列是最灵活的下半部机制,特点:

  • 内核进程上下文中执行
  • 可以睡眠(调用msleep()、等待信号量等)
  • 可以延迟执行
工作队列数据结构
http://www.jsqmd.com/news/226456/

相关文章:

  • 国产麒麟系统卡启动项或图标如何解决
  • 基于职业发展的Python与Java深度对比分析
  • CAD(Creo)各模块的操作和配置
  • 速学!AI应用架构师分享金融市场AI监控系统的实时监控技术优化
  • RAR 、 ZIP、7z 之间的联系与区别
  • 主动学习在AI Agent训练中的应用
  • 工业协议全兼容:实时监控与智能控制
  • 吐血推荐MBA必用TOP10一键生成论文工具
  • 【电动机】液压伺服电动机的状态空间设计与仿真【含Matlab源码 14900期】
  • 【路径规划】基于matlab Fast-RRT二维空间移动机器人改进的运动规划器【含Matlab源码 14901期】复现含文献
  • 基于微信小程序的图书阅读系统【源码+文档+调试】
  • 导师不会告诉你的6款AI论文神器,一键生成超长篇!
  • DOL-CHS-MODS中文美化包:从零开始打造完美游戏体验
  • AO3镜像站技术指南:突破访问限制的完整解决方案
  • 【电动机】基于matlab液压伺服电动机的状态空间设计与仿真【含Matlab源码 14900期】
  • [Linux外设驱动详解]7. 内存管理与 I/O 访问
  • 【光学】基于matlab FLASH核进行投影k空间MRI采集的二维布洛赫模拟【含Matlab源码 14902期】
  • RPG Maker资源提取终极秘籍:轻松解锁游戏素材宝库
  • ReactPage页面编辑器:从内容创作到专业演示文稿的完整指南
  • 3.42 Pulp工具实战:Python线性规划求解器,5分钟上手运筹优化
  • 小米运动智能刷步神器:轻松同步微信支付宝步数全攻略
  • 【光学】FLASH核进行投影k空间MRI采集的二维布洛赫模拟【含Matlab源码 14902期】
  • [Linux外设驱动详解]8. GPIO子系统
  • 3.41 运筹规划问题入门:线性规划、整数规划、混合整数规划详解
  • 工作流自动化方法论:从业务流程优化到零代码配置实战
  • 导师严选8个论文写作工具,一键生成论文工具推荐!
  • 3.36 FasterRCNN算法详解:RPN网络,两阶段检测的巅峰之作
  • 【API渗透】crAPI 靶场的环境搭建与漏洞复现详解
  • 2026必备!8个AI论文写作软件,专科生搞定毕业论文+格式规范!
  • 3.38 工业缺陷检测实战:物体表面缺陷检测,从图像处理到深度学习