首页 > 运维 > linux运维 > 正文

Linux驱动实践:中断处理函数如何【发送信号】给应用层?

星夢妙者
发布: 2025-06-26 12:20:01
原创
328人浏览过

作者:道哥,一位拥有10多年嵌入式开发经验的老兵,专注于c++/c++、嵌入式开发和linux

目录

驱动程序示例代码全貌 Makefile 文件编译、测试 应用程序示例代码全貌 编译、测试 别人的经验,我们的阶梯!

大家好,我是道哥,今天我要为大家讲解的技术知识点是:【中断程序如何发送信号给应用层】。

最近分享的几篇文章都相对基础,涉及字符类设备的驱动程序以及中断处理程序。

虽然现代项目可能用不到这样的技术,但万丈高楼平地起。

只有理解这些最基础的知识点,才能在学习那些进化出来的高级技术时,逐步获得成就感。

如果缺少这些基础环节,很多深层次的东西学起来就会感觉像空中楼阁。

就好比研究Linux内核,如果从Linux 4.x/5.x版本开始研究,可以看到很多“历史遗留”代码。

这些代码见证了Linux一步一步的发展历史,甚至有些人会专门研究Linux 0.11版本的内核源码,因为很多基本思想是相通的。

Alkaid.art
Alkaid.art

专门为Phtoshop打造的AIGC绘画插件

Alkaid.art 153
查看详情 Alkaid.art

今天这篇文章,主要还是以代码实例为主,将之前的两个知识点结合起来:

在中断处理函数中,发送信号给应用层,以此来通知应用层处理相应的中断业务。

Linux驱动实践:中断处理函数如何【发送信号】给应用层?

驱动程序示例代码全貌

首先创建驱动模块目录:

$ cd ~/tmp/linux-4.15/drivers
$ mkdir my_driver_interrupt_signal
$ touch my_driver_interrupt_signal.c
登录后复制

文件内容如下:

#include <linux>
#include <linux>
#include <linux>
#include <linux>
#include <linux>
#include <asm>
#include <linux>
#include <linux>
#include <linux>
#include <linux>
#include <linux>

// 中断号
#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驱动实践:中断处理函数如何【发送信号】给应用层?的详细内容,更多请关注php中文网其它相关文章!

相关标签:
驱动精灵
驱动精灵

驱动精灵基于驱动之家十余年的专业数据积累,驱动支持度高,已经为数亿用户解决了各种电脑驱动问题、系统故障,是目前有效的驱动软件,有需要的小伙伴快来保存下载体验吧!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号