驱动开发-按键中断
编写LED灯的驱动,使用GPIO子系统,里面添加按键的中断处理
1.应用程序发送指令控制LED亮灭
2.按键1 按下,led1电位反转 按键2按下,led2电位反转 按键3 按下,led3电位反转
功能函数
#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>
#include<sys/ioctl.h>//功能码
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)int main(int argc, char const *argv[])
{char buf[128] = {0};int a,b;int fd;while (1){printf("请输入要控制的灯:0(led1) 1(led2) 2(led3)\n");scanf("%d",&a);if(a == 0){fd = open("/dev/myled0", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}}else if(a == 1){fd = open("/dev/myled1", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}}else if(a == 2){int fd = open("/dev/myled2", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}}printf("请输入控制命令:0(关闭) 1(开灯)>");scanf("%d",&b);switch(b){case 1:ioctl(fd,LED_ON);break;case 0:ioctl(fd,LED_OFF);break;}close(fd);}return 0;
}
驱动代码
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include<linux/fs.h>
#include<linux/io.h>
#include<linux/device.h>//功能码
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)unsigned int major;//定义一个变量保存主设备号char kbuf[128]={0};
struct class *cls;
struct device*device;struct device_node *dev_led;
struct device_node *dev;
unsigned int irqno1,irqno2,irqno3;
struct gpio_desc *gpiono1;
struct gpio_desc *gpiono2;
struct gpio_desc *gpiono3;/*myirq{interrupt-parent=<&gpiof>;//引用中断父节点interrupts=<9 0>,<7 0>,<8 0>;//声明和中断父节点的关系 9表示索引号,0表示默认设置
};
*///中断处理函数
irqreturn_t myirq_handler1(int irq,void *dev)
{gpiod_set_value(gpiono1, !gpiod_get_value(gpiono1)); // LED1return IRQ_HANDLED;
}
irqreturn_t myirq_handler2(int irq,void *dev)
{gpiod_set_value(gpiono2, !gpiod_get_value(gpiono2)); // LED2return IRQ_HANDLED;
}
irqreturn_t myirq_handler3(int irq,void *dev)
{gpiod_set_value(gpiono3, !gpiod_get_value(gpiono3)); // LED3return IRQ_HANDLED;
}//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{int a = inode->i_rdev;//获取当前设备文件对应的设备号file->private_data=(void*)MINOR(a);//将次设备号保存到当前文件的file结构中printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{unsigned int a=(unsigned int)file->private_data;switch(a){case 0:if(cmd == LED_ON)gpiod_set_value(gpiono1,1);elsegpiod_set_value(gpiono1,0);break; case 1:if(cmd == LED_ON)gpiod_set_value(gpiono2,1);elsegpiod_set_value(gpiono2,0);break; case 2:if(cmd == LED_ON)gpiod_set_value(gpiono3,1);elsegpiod_set_value(gpiono3,0);break; }return 0;
}int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
//定义一个操作方法结构体变量并且初始化
struct file_operations fops={.open=mycdev_open,.release=mycdev_close,.unlocked_ioctl = mycdev_ioctl,
};static int __init mycdev_init(void)
{int i;// 字符设备驱动注册major = register_chrdev(0, "mychrdev", &fops);if (major < 0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功:major=%d\n", major);// 向上提交目录cls = class_create(THIS_MODULE, "myled");if (IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录信息成功\n");// 向上提交设备节点信息for (i = 0; i < 3; i++){device = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);if (IS_ERR(device)){printk("向上提交设备节点信息失败\n");return -PTR_ERR(device);}}printk("向上提交设备节点成功\n");int ret1,ret2,ret3;//解析按键的设备树节点dev = of_find_node_by_path("/myirq");if(dev==NULL){printk("解析设备树节点失败\n");return -EFAULT;}printk("解析设备树节点成功\n");//根据设备树节点的路径解析设备树信息dev_led = of_find_node_by_path("/leds");if(dev_led==NULL){printk("解析设备树信息失败\n");return -EFAULT;}printk("解析设备树信息成功\n");//根据设备树节点解析出软中断号irqno1 = irq_of_parse_and_map(dev,0);//按键1索引号为0irqno2 = irq_of_parse_and_map(dev,1);//按键2索引号为1irqno3 = irq_of_parse_and_map(dev,2);//按键3索引号为2if(!irqno1|!irqno1|!irqno2){printk("解析软中断号失败\n");return -ENXIO;}printk("解析软中断号成功 irqno=%d %d %d\n",irqno1,irqno2,irqno3);//注册中断ret1 = request_irq(irqno1,myirq_handler1,IRQF_TRIGGER_FALLING,"key1",NULL);ret2 = request_irq(irqno2,myirq_handler2,IRQF_TRIGGER_FALLING,"key2",NULL);ret3 = request_irq(irqno3,myirq_handler3,IRQF_TRIGGER_FALLING,"key3",NULL);if(ret1|ret2|ret3){printk("注册中断失败\n");return -EFAULT;}printk("注册中断成功\n");//根据解析到的设备树信息解析出led的gpio编号// 申请gpio_desc对象并设置输出为低电平gpiono1 = gpiod_get_from_of_node(dev_led, "led1-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono1)){printk("申请gpio1对象失败\n");return -PTR_ERR(gpiono1);}printk("申请gpio1对象成功\n");gpiono2 = gpiod_get_from_of_node(dev_led, "led2-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono2)){printk("申请gpio2对象失败\n");return -PTR_ERR(gpiono2);}printk("申请gpio2对象成功\n");gpiono3 = gpiod_get_from_of_node(dev_led, "led3-gpios", 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono3)){printk("申请gpio对象失败\n");return -PTR_ERR(gpiono3);}printk("申请gpio3对象成功\n");return 0;
}
static void __exit mycdev_exit(void)
{//销毁设备节点信息int i;for(i=0;i<3;i++){device_destroy(cls,MKDEV(major,i));}//销毁目录信息class_destroy(cls);//注销字符设备驱动unregister_chrdev(major,"mychrdev");//注销中断free_irq(irqno1,NULL);free_irq(irqno2,NULL);free_irq(irqno3,NULL);// 灭灯gpiod_set_value(gpiono1, 0);// 释放gpio编号gpiod_put(gpiono1);gpiod_set_value(gpiono2, 0);gpiod_put(gpiono2);gpiod_set_value(gpiono3, 0);gpiod_put(gpiono3);}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");相关文章:
驱动开发-按键中断
编写LED灯的驱动,使用GPIO子系统,里面添加按键的中断处理 1.应用程序发送指令控制LED亮灭 2.按键1 按下,led1电位反转 按键2按下,led2电位反转 按键3 按下,led3电位反转 功能函数 #include<stdlib.h> #inclu…...
数据结构 | 二叉树的应用
目录 一、解析树 二、树的遍历 一、解析树 我们可以用解析树来表示现实世界中像句子或数学表达式这样的构造。 我们可以将((73)*(5-2))这样的数学表达式表示成解析树。这是完全括号表达式,乘法的优先级高于加法和减法,但因为有括号,所以在…...
python:卡尔曼和贝叶斯滤波器
本文分享一个Filerpy的说明文档和代码示例文档,有关于 Python 中的卡尔曼和贝叶斯滤波器。该方法可以应用于气象遥感等领域。 说明文档:https://filterpy.readthedocs.io/en/latest/kalman/KalmanFilter.html 参考代码链接:https://nbviewer.…...
走进 Go 语言基础语法 | 青训营 (1)
Powered by:NEFU AB-IN 文章目录 走进 Go 语言基础语法 | 青训营 (1)代码注释代码模板 走进 Go 语言基础语法 | 青训营 (1) 代码注释 /** Author: NEFU AB-IN* Date: 2023-08-06 09:44:15* FilePath: \GoTest\a.go* LastEditTime: 2023-08-06 11:00:45*/ package mainimport (&…...
基于边缘无线协同感知的低功耗物联网LPIOT技术:赋能智慧园区方案以及数字工厂领域
回到2000年左右,物联网的底层技术支撑还是“ZigBee”,虽然当时ZigBee的终端功耗指标其实也并不庞大,但是,“拓扑复杂导致工程实施难度大”、“网络规模小导致的整体效率低下”都成为限制其发展的主要因素。 LPWAN,新一…...
【《快速构建AI应用——AWS无服务器AI应用实战》——基于云的解决方案快速完成人工智能项目的指南】
基于云的人工智能服务可以自动完成客户服务、数据分析和财务报告等领域的各种劳动密集型任务。其秘诀在于运用预先构建的工具,例如用于图像分析的Amazon Rekognition或用于自然语言处理的AWS Comprehend。这样,就无须创建昂贵的定制软件系统。 《快速构…...
vue运行在IE浏览器空白报错SCRIPT1006: 缺少‘)‘ -【vue兼容IE篇】
其他浏览器均正常,但是切换ie模式,打开空白,F12打开报错缺少‘)‘ ,如下图 在搜狗浏览器下点开报错:定格在crypto-js处 解决: 步骤一:使用npm安装babel-polyfill 依赖(已安装了可忽…...
接口自动化测试Mock Get和Post请求
Mock可以模拟一个http接口的后台响应,可以模拟request,response 下载 moco-runner-0.11.0-standalone.jar 下载链接: https://pan.baidu.com/s/1bmFzvJPRnDlQ-cmuJ_3iRg 提取码: kpjv 确保安装了jdk,cmd下可以运行java -version 一、模拟不带参的get请求…...
WPF上位机8——C#与MySQL
ADO.NET 数据库连接 数据插入、删除、更改 数据查询 带单个参数 带多个参数 using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Wp…...
[JAVAee]网络编程-套接字Socket
目录 基本概念 发送端与接收端 请求与响应 编辑客户端与服务器 Socket套接字 分类 数据报套接字 流套接字传输模型 UDP数据报套接字编程 DatagramSocket API DatagramPacket API InetSocketAddress API 示例一: 示例二: TCP流数据报套接字编程 ServerSock…...
批量导出pdf为zip文件(可以修改zip中pdf名称)
核心代码 public static void compressZip1(HashMap<String,File> map, String rootPath, String zipFileName) throws FileNotFoundException {FileOutputStream fileOutputStream new FileOutputStream(zipFileName);ZipOutputStream zipOutputStream new ZipOutputS…...
[国家集训队] Tree II 题解报告
[国家集训队] Tree II 一道真板子题 就是练习LCT懒标记的题目 除了翻转标记以外还要维护乘法标记和加法标记 注意加法标记和乘法标记的维护!!! 加法标记 因为splay的区间大小不是固定的,所以我们要维护size,并且…...
【redis】docker搭建redis集群
docker搭建redis集群,超级简单方便。 # 1. 拉取redis. 目前我拉取最新的是7.0.12 docker pull redis # 2. 下载配置文件 wget https://raw.githubusercontent.com/redis/redis/7.0/redis.conf # 3. 移到对应目录 mkdir -p /opt/docker/redis mv redis.conf /opt/d…...
前端个人年度工作述职报告(二十篇)
前端个人年度工作述职报告篇1 尊敬的各位领导、各位同仁: 大家好!按照20__年度我公司就职人员工作评估的安排和要求,我认真剖析、总结了自己的工作情况,现将本人工作开展情况向各位领导、同仁做以汇报,有不妥之处,希…...
TypeScript 编译配置
TypeScript的编译配置: 对单独一个ts文件进行监听编译 可使用tsc demo.ts -w 如果想对所有ts文件进行监听编译,监听到变化就自己编译,可以直接创建一个tsconfig.json文件。内容空着也OK:{},执行 tsc 或 tsc -w 如果有…...
使用DMA传输实现单片机高效串口转发——以STM32系列为例
使用DMA传输实现单片机高效串口转发——以STM32系列为例 DateAuthorVersionNote2023.08.06Dog TaoV1.01. 完成了文档的撰写。 文章目录 使用DMA传输实现单片机高效串口转发——以STM32系列为例应用场景实现流程源码示例串口与中断配置DMA外设配置DMA发送数据函数串口中断服务函…...
一文了解 Android Auto 车载开发~
作者:牛蛙点点申请出战 背景 我的的产品作为一个海外音乐播放器,在车载场景听歌是一个很普遍的需求。在用户反馈中,也有很多用户提到希望能在车上播放音乐。同时车载音乐也可以作为提升用户消费时长一个抓手。 出海产品,主要服务…...
Pixel4 安卓源码及内核修改编译教程 | 基于Android12 AOSP
之前整理了 Pixel4上的源码过程,下载的话大家可以去镜像网站下载,可以节约很多时间。 实验设备:Ubuntu18.04 32G2T Pixel4 文章目录 一、安卓源码下载1.准备下载环境(1)安装Python 3.9(2)安装g…...
如何做好Code Review
本文主要从我们为什么需要CR?CR面临哪些挑战?CR的最佳实践几个方面分析,希望可以给读者一些参考。 为什么需要CR? 代码质量 定性来看,大家都认可Code Review(后文简称CR)能显著改善代码质量&…...
Unity技术框架集合、Unity技术栈汇总
引擎技术尝试 [Animancer-Pro] (https://assetstore.unity.com/packages/tools/animation/animancer-pro-116514) (基于Playable的简单强大的动画解决方案)[ProBuilder/UModeler] (https://assetstore.unity.com/packages/tools/modeling/umodeler-80868) (快速关卡原型构建…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
