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

Linux驱动程序机制

在近几年的 Linux 内核(特别是 5.x 到现代 6.x+ 版本)中,许多老旧机制已经边缘化甚至在被清退(比如tasklet)。下面列出主流任然大量使用的同步与异步机制。

1. 进程同步与阻塞控制

休眠与唤醒 (Sleep & Wakeup)

  • 核心 API:wait_event(wq_head, condition)/wait_event_interruptible()负责睡;wake_up(&wq_head)/wake_up_interruptible()负责醒。

  • 实现载体:依赖内核的等待队列(Wait Queue)机制,基础数据结构为wait_queue_head_t、wait_queue_entry 。

    /* wait_queue_entry::flags */ #define WQ_FLAG_EXCLUSIVE 0x01 #define WQ_FLAG_WOKEN 0x02 #define WQ_FLAG_BOOKMARK 0x04 #define WQ_FLAG_CUSTOM 0x08 #define WQ_FLAG_DONE 0x10 #define WQ_FLAG_PRIORITY 0x20 /* * A single wait-queue entry structure: */ struct wait_queue_entry { unsigned int flags; void *private; wait_queue_func_t func; struct list_head entry; }; struct wait_queue_head { spinlock_t lock; struct list_head head; }; typedef struct wait_queue_head wait_queue_head_t;

    阻塞与非阻塞 (Blocking/Non-blocking)

  • 实现载体:它不是独立的内核 API,而是VFS(虚拟文件系统)层的一种应用属性。应用层通过O_NONBLOCK标志打开文件。

  • 驱动实现:驱动的.read.write接口内部,去检查filp->f_flags & O_NONBLOCK。如果无数据且是非阻塞,立刻返回-EAGAIN;如果是阻塞,则在内部调用上述的wait_event()让进程去睡觉。

2. I/O 多路复用与通知

  • POLL/Epoll 机制

    • 核心 API:驱动层实现struct file_operations中的.poll接口,内部必须调用内核提供的poll_wait(filp, wait_address, pwait)

    • 应用层对应:应用层调用select()poll()epoll_wait()

  • 异步通知 (Async Notification)

    • 核心 API:驱动层实现.fasync接口,内部使用fasync_helper()来初始化和管理队列;当硬件有数据时,驱动调用kill_fasync(&fasync_queue, SIGIO, POLL_IN)

3. 时间管理

内核定时器 (Timers)

  • 核心 API:*低分辨率定时器(基于 Jiffies):timer_setup(timer, callback, flags)mod_timer()del_timer()

    • 高分辨率定时器(纳秒级):hrtimer_init()hrtimer_start()

4. 中断下半部延期执行(现代内核主流分类)

  • Tasklet(已被明确标记为弃用/淘汰):早期基于软中断(Softirq)实现的轻量级下半部。因为运行在软中断上下文(不能休眠、调试极难、容易导致系统高延迟),现代内核正在全面将其用Threaded IRQWorkqueue进行替换

  • 软中断

  • 用于缩短硬中断的处理时间(软中断机制主要是由系统内核自身处理底层事件,普通应用层或驱动层开发者极少直接调用)

  • 工作队列 (Workqueue - 现代重型主力):

    • 核心 API:INIT_WORK(work, func)schedule_work(&work);或者自定义队列:alloc_workqueue()queue_work()

    • 实现载体:运行在进程上下文(内核创建的kworker线程中),允许休眠,适合做耗时的 I/O、内存分配、加锁等操作。

    • 注意workqueue 和硬件中断没有直接关系 不一定非要在硬中断才能调用 它的核心逻辑是“workqueue:我想让一个函数 “稍后异步执行”,由内核线程帮我跑。

      struct work_struct my_work; //包含你写的my_work_function INIT_WORK(&my_work, my_work_function); schedule_work(&my_work) //1、把 work 加入全局工作队列 system_wq //2、唤醒后台的 kworker 线程 //函数真正执行,是稍后 kworker 线程自己去取出来跑的! 这个函数可能在中断上半部被调用 所以要立即返回 //或者丢进你自己创建的专属workqueue队列 struct workqueue_struct *my_wq; my_wq = alloc_workqueue("my_own_wq", WQ_HIGHPRI, 0); // 👆 这是内核里显示的线程名字(给 ps 看的) queue_work(my_wq, &my_work); // 提交到自己的队列 //如果想要延时一段时间再入队 让线程执行 // 1. 定义带延时的 work struct delayed_work my_dwork; // 2. 初始化 INIT_DELAYED_WORK(&my_dwork, my_work_func); // 3. 调度:延时 N 毫秒后执行 schedule_delayed_work(&my_dwork, msecs_to_jiffies(100)); // 100ms 后才会真正入队、执行
  • 中断线程化 (Threaded IRQ - 现代轻量级主力):

    • 核心 API:request_threaded_irq(irq, handler, thread_fn, irqflags, devname, dev_id)

    • 现代地位:近几年内核最推崇的主流机制。它把中断处理一分为二:handler是顶半部(快进快出),thread_fn是下半部。内核会自动为它创建一个专用的内核线程。允许休眠,且可以直接受实时调度器(RT FIFO/RR)管辖,极大地提升了系统的实时性。

它们之间关系

流派分类涵盖的机制底层核心本质权威视角的逻辑解释

1. 同步执行控制流

(Synchronous Control)

• 休眠与唤醒

• 阻塞 I/O (wait_event)

控制流的阻塞与挂起这是纯粹的同步机制。它的特征是**“线性且单线程”。应用程序(或内核当前执行流)因为硬件条件不满足,主动交出 CPU 睡觉,等条件满足了再就地复活**继续往下走。在时序上,它是一条连贯的单向线。

2. 跨边界事件通知

(Cross-Boundary Notification)

• POLL / Epoll 机制

• 异步通知 (fasync)

内核向应用层的事件通知

解决的是“应用层与内核/硬件层”的信息不对称。

POLL/Epoll本质是同步非阻塞/事件驱动(Reactor 模式):应用层把耳朵贴在驱动的等待队列上,有数据了,内核通知应用层“醒来”,应用层自己发起读取。

fasync本质是纯异步通知(信号机制):应用层完全在干别的,驱动有数据了直接向应用层发射一个SIGIO信号(相当于硬件中断的软件模拟),强行打断应用层的执行流去执行信号处理函数。

3. 异步任务延迟执行

(Asynchronous Task Deferral)

• 内核定时器 (Timer)

• 传统 Tasklet

• 工作队列 (Workqueue)

• 中断线程化 (Threaded IRQ)

内核上下文的异步调度这是纯粹的异步机制。解决的是“硬件中断(Top Half)不能耗时、不能睡眠”的系统矛盾。它的本质是**“开一张延期支票”:硬中断十万火急,接单后立刻退出(开中断);把复杂的后续业务打包丢给 Workqueue 或 Threaded IRQ,由内核在未来的、更安全的、甚至是独立的线程上下文**中去异步执行。

总结:逻辑主线

如果你去翻阅 Linux 内核最权威的《Linux Device Drivers》(LDD3)或者现代 Linux 社区的补丁集(LWN.net),你会发现内核设计者看待这些机制的逻辑非常简单统一:

  1. 为了让硬件和内核高效协作,且不卡死 CPU$\rightarrow$ 诞生了【异步任务延迟执行机制】(中断线程化、工作队列、定时器)。

  2. 当驱动在后台把硬件数据捞上来了,为了让应用层安全地拿到数据$\rightarrow$ 诞生了【同步执行控制流】(让应用阻塞休眠,好了再叫醒)和【跨边界事件通知】(用 Epoll 批量通知,或者用 Signal 暴力异步通知)。

它们就像一套组合拳:下半部机制(如 Threaded IRQ)在内核后台异步把网卡或传感器数据收好,然后调用wake_up()kill_fasync(),转手化作一个同步阻塞的唤醒事件或一个异步的信号通知,最终送达用户态应用程序。

http://www.gsyq.cn/news/1496626.html

相关文章:

  • 聚焦脑机接口领域基础研究:国家自然科学基金委与术理创新共同设立民营企业创新发展联合基金(术理创新)
  • 2026年实测:各类大赛人气投票链接生成方法,3分钟搞定(免费+强防刷) - 微信投票小程序
  • 高效核销网点系统开发全解析
  • 阳极与阴极浇铸质量检测仪哪家靠谱?上规模生产企业青岛普锐思介绍 - 品牌推荐大师1
  • 2026年佛山铰链供应商深度横评:全屋定制五金一站式采购避坑指南 - 年度推荐企业名录
  • Linux基础知识(二)
  • AI技术落地商业化破局:明图科技以技术创新驱动数字产业实景发展
  • 2026求职季5款主流AI面试工具深度测评:从全真模拟到定向突破
  • 【华为OD机试真题 新系统】1019、文档特征提取 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)
  • 别再死记硬背了!用一张图+对比表彻底搞懂Vue3自定义指令的生命周期
  • Claude Code 超详细完整指南(手把手教学)
  • JUC 概述
  • 屏蔽多云差异:多云底座的架构设计与实践
  • 温州洞头区商圈实测:当前金价与回收避坑指南 - 专业黄金回收
  • 下水管道爬行检测机器人品牌推荐 - 资讯焦点
  • 文科生零基础不会编程,为什么也要重视人工智能应用?
  • 2026绍兴防水补漏哪家靠谱?正规公司排名及避坑价格指南 - 苏易修缮
  • 2026年实测免费图片格式转换软件?图片拼图压缩加水印全搞定 - 热点速览
  • 杭州富阳区通下水通马桶地漏,菜池厨房下水,打捞异物卫生间除臭--2026杭州疏通top排行榜推荐公司 - 同城资讯
  • 2026年四川首选白酒加盟品牌优选参考,不容错过! - 企业推荐官
  • 合肥市消防管无声漏水检测,长期慢漏暗漏,仪器深度扫描排查--2026年室外消防管漏水检测维修公司top推荐热榜 - 同城资讯
  • 广元黄金回收2026大盘价当面结算无套路 - 润富黄金回收
  • UVM验证进阶:拆解start_item源码,搞懂sequencer参数怎么用才高效
  • 合肥市大型园区消防管道测漏公司,地埋管网渗漏精准探测,全天候上门服务电话-消防漏水检测top推荐公司 - 同城资讯
  • 林地全自动拓荒机2026年|选源头厂家还是中间商? - 博客万
  • 从硬件总线视角看TriCore多核锁:TC264的CMPSWAP.W指令如何避免抢锁冲突
  • 2026 长治厨卫屋面地下室漏水瓷砖空鼓测评:吉修匠 99.8 分五星榜首 - 吉修匠
  • 2026年乐平管道疏通推荐指南:从家庭到商铺全场景覆盖 实体团队专业设备省心选择 - 本地品牌推荐
  • 现场写作/最美笔记/英文书写大赛投票怎么一键生成?微信小程序免费测评|众星评选实测推荐 - 微信投票小程序
  • 2026年主流粮食烘干机厂家品牌解析及选购指南 - 博客万