Linux驱动实践:中断处理函数如何【发送信号】给应用层?
发布时间 - 2025-06-26 00:00:00 点击率:次作者:道哥,一位拥有10多年嵌入式开发经验的老兵,专注于c++/c++、嵌入式开发和linux。
目录
驱动程序示例代码全貌 Makefile 文件编译、测试 应用程序示例代码全貌 编译、测试 别人的经验,我们的阶梯!
大家好,我是道哥,今天我要为大家讲解的技术知识点是:【中断程序如何发送信号给应用层】。
最近分享的几篇文章都相对基础,涉及字符类设备的驱动程序以及中断处理程序。
虽然现代项目可能用不到这样的技术,但万丈高楼平地起。
只有理解这些最基础的知识点,才能在学习那些进化出来的高级技术时,逐步获得成就感。
如果缺少这些基础环节,很多深层次的东西学起来就会感觉像空中楼阁。
就好比研究Linux内核,如果从Linux 4.x/5.x版本开始研究,可以看到很多“历史遗留”代码。
这些代码见证了Linux一步一步的发展历史,甚至有些人会专门研究Linux 0.11版本的内核源码,因为很多基本思想是相通的。
今天这篇文章,主要还是以代码实例为主,将之前的两个知识点结合起来:
在中断处理函数中,发送信号给应用层,以此来通知应用层处理相应的中断业务。
驱动程序示例代码全貌
首先创建驱动模块目录:
$ cd ~/tmp/linux-4.15/drivers $ mkdir my_driver_interrupt_signal $ touch my_driver_interrupt_signal.c
文件内容如下:
#include#include #include #include #include #include #include #include #include #include #include // 中断号 #define IRQ_NUM 1 // 定义驱动程序的 ID,在中断处理函数中用来判断是否需要处理 #define IRQ_DRIVER_ID 1234 // 设备名称 #define MYDEV_NAME "mydev" // 驱动程序数据结构 struct myirq { int devid; }; struct myirq mydev = { IRQ_DRIVER_ID }; #define KBD_DATA_REG 0x60 #define KBD_STATUS_REG 0x64 #define KBD_SCANCODE_MASK 0x7f #define KBD_STATUS_MASK 0x80 // 设备类 static struct class *my_class; // 用来保存设备 struct cdev my_cdev; // 用来保存设备号 int mydev_major = 0; int mydev_minor = 0; // 用来保存向谁发送信号,应用程序通过 ioctl 把自己的进程 ID 设置进来。 static int g_pid = 0; // 用来发送信号给应用程序 static void send_signal(int sig_no) { int ret; struct siginfo info; struct task_struct *my_task = NULL; if (0 == g_pid) { // 说明应用程序没有设置自己的 PID printk("pid[%d] is not valid! \n", g_pid); return; } printk("send signal %d to pid %d \n", sig_no, g_pid); // 构造信号结构体 memset(&info, 0, sizeof(struct siginfo)); info.si_signo = sig_no; info.si_errno = 100; info.si_code = 200; // 获取自己的任务信息,使用 的是 RCU 锁 rcu_read_lock(); my_task = pid_task(find_vpid(g_pid), PIDTYPE_PID); rcu_read_unlock(); if (my_task == NULL) { printk("get pid_task failed! \n"); return; } // 发送信号 ret = send_sig_info(sig_no, &info, my_task); if (ret < 0) { printk("send_sig_info failed\n"); } }
这段代码展示了如何在中断处理函数中发送信号给应用层,确保应用层能够及时处理中断业务。
# linux
# ai
# c++
# 自己的
# 应用层
# 应用程序
# 的是
# 万丈高楼平地起
# 我是
# 就会
# 空中楼阁
# 这段
# 数据结构
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何为不同团队 ID 动态生成多个独立按钮
如何用PHP快速搭建CMS系统?
BootStrap整体框架之基础布局组件
Python并发异常传播_错误处理解析【教程】
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】
详解Oracle修改字段类型方法总结
Swift中swift中的switch 语句
Laravel API资源类怎么用_Laravel API Resource数据转换
如何在阿里云虚拟服务器快速搭建网站?
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
如何用虚拟主机快速搭建网站?详细步骤解析
Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
Laravel如何升级到最新版本?(升级指南和步骤)
三星网站视频制作教程下载,三星w23网页如何全屏?
Laravel Docker环境搭建教程_Laravel Sail使用指南
Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
使用豆包 AI 辅助进行简单网页 HTML 结构设计
瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口
如何实现建站之星域名转发设置?
制作旅游网站html,怎样注册旅游网站?
如何在IIS中新建站点并解决端口绑定冲突?
Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制
微信小程序 canvas开发实例及注意事项
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
JS中对数组元素进行增删改移的方法总结
Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
bing浏览器学术搜索入口_bing学术文献检索地址
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
Laravel如何处理文件下载请求?(Response示例)
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权
微信小程序 wx.uploadFile无法上传解决办法
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
如何用狗爹虚拟主机快速搭建网站?
Android Socket接口实现即时通讯实例代码
Laravel中的Facade(门面)到底是什么原理
如何在云主机快速搭建网站站点?
香港服务器选型指南:免备案配置与高效建站方案解析
Python自动化办公教程_ExcelWordPDF批量处理案例
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
php 三元运算符实例详细介绍
如何快速查询网址的建站时间与历史轨迹?
Firefox Developer Edition开发者版本入口
如何彻底删除建站之星生成的Banner?
下一篇:C++ 二叉树的镜像实例详解
下一篇:C++ 二叉树的镜像实例详解


的是 RCU 锁
rcu_read_lock();
my_task = pid_task(find_vpid(g_pid), PIDTYPE_PID);
rcu_read_unlock();
if (my_task == NULL) {
printk("get pid_task failed! \n");
return;
}
// 发送信号
ret = send_sig_info(sig_no, &info, my_task);
if (ret < 0) {
printk("send_sig_info failed\n");
}
}