Linux内核驱动开发-001字符设备开发-内核中断驱动独立按键+等待队列优化

1驱动程序

/*************************************************************************> File Name: key_wait.c> Author: yas> Mail: rage_yas@hotmail.com> Created Time: 2024年04月23日 星期二 13时20分42秒************************************************************************/#if 1
/*=========================The key_wait driver=========================*//*==========头文件包含==========*/
#include <linux/init.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/irqreturn.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <mach/irqs.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/wait.h>
#include <linux/sched.h>/*==========函数声明==========*/static int __init key_driver_init(void);static int key_driver_open(struct inode *node, struct file *fp);
static ssize_t key_driver_read(struct file *fp, char __user *user_buffer, size_t len, loff_t *offset);
static ssize_t key_driver_write(struct file *fp, const char __user *user_buffer, size_t len, loff_t *offset);
static int key_driver_close(struct inode *node, struct file *fp);void disable_irq_r(void);
void free_irq_r(void);
static void __exit key_driver_exit(void);/*==========全局变量==========*//*保存键值*/
static int key = 0;/*字符设备文件操作结构体*/
static struct file_operations fops =
{.owner = THIS_MODULE,.open = key_driver_open,.read = key_driver_read,.write = key_driver_write,.release = key_driver_close
};/*杂项设备结构体*/
static struct miscdevice key_dev = 
{.minor = MISC_DYNAMIC_MINOR,.name = "key_r",.fops = &fops,
};/*===全局变量-等待队列===*/
/*等待队列头*/
static wait_queue_head_t wq;
/*等待条件*/
static int condition;/*******************************************************************************
* 函 数 名	: key_interrupt
* 函数功能	: 处理中断任务
* 输    入  : 
*           irq : 中断号
*           *p  :中断处理函数传参,一般传【NULL】
* 输    出  :
*   irqreturn_t :表示中断由该设备处理,是一个枚举类型
*******************************************************************************/
irqreturn_t key_interrupt(int irq, void *p)
{printk("key_interrupt\n");if(irq == IRQ_EINT8){key = 1;}else if(irq == IRQ_EINT11){key = 2;}condition=1;//按键按下->触发中断->条件为真->唤醒队列wake_up(&wq);//唤醒队列return IRQ_HANDLED;
}/*******************************************************************************
* 函 数 名	: key_driver_init
* 函数功能	: 
* 输    入  : 							
* 输    出  :
*******************************************************************************/
static int __init key_driver_init(void)
{int ret;/* 1 注册杂项设备*/ret = misc_register(&key_dev);if(ret <  0){printk("misc_register is failed\n");goto misc_register_err;}/* 2 注册中断-【中断号】-【中断处理函数指针】-【中断产生的条件和系统处理中断时的行为(这里处理中断时不响应其他中断)】-【给中断名命名】-【中断服务函数传参-NULL】*/ret = request_irq(IRQ_EINT8, key_interrupt, IRQF_TRIGGER_FALLING | IRQF_DISABLED, "key1", NULL);if(ret < 0){printk("request_irq is failed\n");goto request_irq_err;}/* 3 初始化等待队列*/init_waitqueue_head(&wq);printk("key_driver_init OK\n");return 0;request_irq_err:misc_deregister(&key_dev);
misc_register_err:return -1;
}/*******************************************************************************
* 函 数 名	: key_driver_open
* 函数功能	: 
* 输    入  : 							
* 输    出  :
*******************************************************************************/
static int key_driver_open(struct inode *node, struct file *fp)
{printk("request_irq OK\n");return 0;
}/*******************************************************************************
* 函 数 名	: key_driver_read
* 函数功能	: 
* 输    入  : 							
* 输    出  :
*******************************************************************************/
static ssize_t key_driver_read(struct file *fp, char __user *user_buffer, size_t len, loff_t *offset)
{condition=0;/*等待事件中断,在更改任何可能改变等待条件结果的变量后,必须调用【wake_up】-要等待的等待队列-要等待的时间*/wait_event_interruptible(wq,condition);copy_to_user(user_buffer, &key, sizeof(key));key = 0;return sizeof(key);
}/*******************************************************************************
* 函 数 名	: key_driver_write
* 函数功能	: 
* 输    入  : 							
* 输    出  :
*******************************************************************************/
static ssize_t key_driver_write(struct file *fp, const char __user *user_buffer, size_t len, loff_t *offset)
{return 0;
}/*******************************************************************************
* 函 数 名	: key_driver_close
* 函数功能	: 
* 输    入  : 							
* 输    出  :
*******************************************************************************/
static int key_driver_close(struct inode *node, struct file *fp)
{return 0;
}
/*******************************************************************************
* 函 数 名	: disable_irq_r
* 函数功能	: 禁止中断
* 输    入  : 							
* 输    出  :
*******************************************************************************/
void disable_irq_r(void)
{/*禁止中断,如果中断正在执行,则等待中断执行结束后再禁止它*/disable_irq(IRQ_EINT8);
}/*******************************************************************************
* 函 数 名	: free_irq_r
* 函数功能	:
* 输    入  :
* 输    出  :
*******************************************************************************/
void free_irq_r(void)
{/*注销中断*/free_irq(IRQ_EINT8, NULL);
}
/*******************************************************************************
* 函 数 名	: key_driver_exit
* 函数功能	: 
* 输    入  : 							
* 输    出  :
*******************************************************************************/
static void __exit key_driver_exit(void)
{disable_irq_r();//禁止中断free_irq_r();//注销中断misc_deregister(&key_dev);
}module_init(key_driver_init);
module_exit(key_driver_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("XXX");
/*=========================The key_wait driver=========================*/
#endif/*=========================The key_wait driver=========================
*总结:
* 1 等待队列:
*  定义全局变量(等待队列头,队列唤醒的条件)->初始化等待队列(创建该按键中断的等待队列)->等待事件中断(即有按键按下)->唤醒等待队列(条件为真,唤醒等待队列)
*  
* 要点:
* 读时等待
* 中断发生时唤醒
* 
*
*
* */

2应用程序

/*************************************************************************> File Name: main.c> Author: yas> Mail: rage_yas@hotmail.com> Created Time: 2024年04月21日 星期日 15时56分47秒************************************************************************/#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>int main(void)
{  
#if 1
/*====================key-r====================*/    int fd=0;int n=0;fd=open("dev/key_r",O_RDWR);if(fd<0){printf("opening is failed\n");return -1;}while(1){read(fd,&n,4);printf("%d\n",n);sleep(1);}return 0;
/*========================================*/    
#endif
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/830075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV 实现重新映射

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV 实现霍夫圆变换 下一篇 :OpenCV实现仿射变换 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 一个。使用 OpenCV 函数 cv&#xff1a;&#xff1a;remap 实现简单的重新…

20240428如何利用IDM下载磁链视频

缘起&#xff1a; https://weibo.com/tv/show/1034:4864336909500449 中国获奖独立纪录片《阿辉》揭秘红灯区“教父”的生存法则 5,751次观看 1年前 发布于 陕西 身为里中横 67.7万粉丝 互联网科技博主 微博原创视频博主 头条文章作者 https://weibo.com/tv/show/1034:4864…

数据通信-A

数据通信 一、数据通信网络基础二、VRP系统三、eNSP配置命令 不是从零开始&#xff0c;有一些基础&#xff0c;主要记录配置命令。一、数据通信网络基础 图标&#xff1a;主要是认识第一行。 常见术语&#xff1a;数据通信网络最基本的功能是实现数据互通。 数据载荷&#…

解决IDEA下springboot项目打包没有主清单属性

1.问题出现在SpringBoot学习中 , 运行maven打包后无法运行 报错为spring_boot01_Demo-0.0.1-SNAPSHOT.jar中没有主清单属性 SpringBoot版本为 2.6.13 Java 版本用的8 解决方法 1.执行clean 删除之前的打包 2.进行打包规范设置 2.1 3.进行问题解决 (借鉴了阿里开发社区) 使用…

[嵌入式系统-53]:嵌入式系统集成开发环境大全

目录 一、嵌入式系统集成开发环境分类 二、由MCU芯片厂家提供的集成开发工具 三、由嵌入式操作提供的集成开发工具 四、由第三方工具厂家提供的集成开发工具 一、嵌入式系统集成开发环境分类 嵌入式系统集成开发工具和集成开发环境可以按照不同的分类方式进行划分&#xff…

【LAMMPS学习】八、基础知识(5.2)粒度模型

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

将针孔模型相机 应用到3DGS

Motivation 3DGS 的 投影采用的是 CG系的投影矩阵 P P P, 默认相机的 principal point (相机光心) 位于图像的中点处。但是 实际应用的 绝大多数的 相机 并不满足这样一个设定&#xff0c; 因此我们 需要根据 f , c x , c y {f,c_x, c_y} f,cx​,cy​ 这几个参数重新构建3D …

centos 7 yum install -y nagios

centos 7 systemctl disable firewalld --now vi /etc/selinux/config SELINUXdisabled yum install -y epel-release httpd nagios yum install -y httpd nagios systemctl enable httpd --now systemctl enable nagios --now 浏览器 IP/nagios 用户名&#xff1a;…

vue学习的预备知识为学好vue打好基础

目录 Vue是什么 &#xff1f;如何使用Vue &#xff1f;Vue ApiVue入口apiVue实例apiVue函数api 无构建过程的渐进式增强静态HTMLVue模块化构建工具npmyarnWebpackvue-cliVite Vue是什么 &#xff1f; 文章基于Vue3叙述。 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于…

十大USDT交易平台大全XEX交易所

USDT是一种基于比特币区块链网络的加密代币&#xff0c;主要运用于数字货币交易平台&#xff0c;以稳定币为主。USDT的核心价值在于其与真实货币的固定兑换比率1:1&#xff0c;所以被称为Tether。随着加密货币市场的不断壮大&#xff0c;越来越多的交易平台开始支持USDT&#x…

2024深圳杯(东北三省)数学建模C题完整论文讲解(含完整python代码及所有残骸音爆位置求解结果)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了2024深圳杯&#xff08;东北三省数学建模联赛&#xff09;A题多个火箭残骸的准确定位完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊…

【vscode环境配置系列】vscode远程debug配置

VSCODE debug环境配置 插件安装配置文件debug 插件安装 安装C/C, C/C Runner 配置文件 在项目下建立.vscode文件夹&#xff0c;然后分别建立c_cpp_properties.json&#xff0c; launch.json&#xff0c;tasks.json&#xff0c;内容如下&#xff1a; c_cpp_properties.json:…

如何解决pycharm创建项目报错 Error occurred when installing package ‘requests‘. Details.

&#x1f42f; 如何解决PyCharm创建项目时的包安装错误&#xff1a;‘requests’ &#x1f6e0;️ 文章目录 &#x1f42f; 如何解决PyCharm创建项目时的包安装错误&#xff1a;requests &#x1f6e0;️摘要引言正文&#x1f4d8; **问题分析**&#x1f680; **更换Python版本…

如何利用快解析软件搭建映射端口

端口映射&#xff0c;就是将内网中主机的一个端口映射到外网主机的一个端口&#xff0c;提供相应的服务&#xff0c;当用户访问外网IP的这个端口时&#xff0c;服务器自动将请求映射到对应局域网内部的机器上。如何才能实现端口映射&#xff1f;今天小编给大家介绍两种方法&…

fetch请求后端返回文件流,并下载。

前端&#xff1a; <script src"~/layui/layui.js"></script> <script src"~/Content/js/common/js/vue.min.js"></script> <script src"~/Content/js/common/js/jquery-1.10.2.min.js"></script><styl…

QT学习篇—qt软件安装

qt下载网址http://download.qt.io/new_archive/qt/ QT官网Qt | Tools for Each Stage of Software Development LifecycleAll the essential Qt tools for all stages of Software Development Lifecycle: planning, design, development, testing, and deployment.https:…

虚拟机扩容-根目录挂载sda1的空间不足

提醒&#xff01;不管成不成功&#xff0c;一定要先备份一份虚拟机&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 走过路过点个关注吧&#xff0c;想到500粉丝&#xff0c;哭。一、查看分区情况 df -h可以看到/dev/sda1已经被占满了 2.关闭虚拟机&#xff…

TinyShell后门通信模型剖析

TinyShell后门通信模型剖析 通过对TinyShell后门的外联通信函数进行剖析&#xff0c;梳理其通信过程如下&#xff1a; 调用gettimeofday函数及getpid函数获取当前时间tv及进程pid&#xff0c;将tv和pid作为SHA1算法的输入&#xff0c;生成得到20字节的IV1数据调用gettimeofda…

OpenHarmony实战开发-使用通用事件、焦点事件

基本概念 焦点 指向当前应用界面上唯一的一个可交互元素&#xff0c;当用户使用键盘、电视遥控器、车机摇杆/旋钮等非指向性输入设备与应用程序进行间接交互时&#xff0c;基于焦点的导航和交互是重要的输入手段。 默认焦点 应用打开或切换页面后&#xff0c;若当前页上存在…

工业异常检测

工业异常检测在业界和学界都一直是热门&#xff0c;近期其更是迎来了全新突破&#xff1a;与大模型相结合&#xff01;让异常检测变得更快更准更简单&#xff01; 比如模型AnomalyGPT&#xff0c;它克服了以往的局限&#xff0c;能够让大模型充分理解工业场景图像&#xff0c;判…