使用中断子系统实现对LED灯的控制
中断顶半部:不允许耗时操作
代码流程:
1、基于字符设备驱动的注册(手动/自动)
2、基于设备树文件的自定义完成(myled, myirq)
2、基于GPIO子系统实现led的点亮(流水/测试文件控制)
3、中断子系统操作流程
3.1根据路径解析设备树节点信息
3.2根据设备树节点指针解析获得软中断号
API: irq_of_parse_and_map
3.3自定义中断处理函数(其内部完成对led灯的亮灭操作)
API: irqreturn_t irq_handler(int irqno, void *dev)
3.4注册要使用的中断号进入内核
API: request_irq
3.5注销软中断号
API: free_irq
注:循环注册需使用到irq_request的最后一个参数(void *),且循环注册需要循环注销
代码示例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/of_irq.h>#define MAX 3struct device_node *node;
struct device_node *node2;
struct gpio_desc *desc1;
struct gpio_desc *desc2;
struct gpio_desc *desc3;
unsigned int irqno[3];
char* irqname[3] = {"key1", "key2", "key3"};
//int gpiono;int major;
char kbuf[128]={0};//中断处理函数
irqreturn_t irq_handler(int irqno, void *dev)
{int i = (int *)dev;switch(i){case 0:gpiod_set_value(desc1, 0);break;case 1:gpiod_set_value(desc2, 0);break;case 2:gpiod_set_value(desc3, 0);break;}return IRQ_HANDLED;//表示当前中断被处理了
}int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *off)
{int ret;if(size>sizeof(kbuf)) //size传过来的是sizeof(ubuf),如果ubuf>kbuf,那么实际长度为kbufsize = sizeof(kbuf);ret = copy_to_user(ubuf, kbuf, size);if(ret){printk("copy to user failed...\n");return -EIO;}printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *off)
{int ret;if(size>sizeof(kbuf))size = sizeof(kbuf);ret = copy_from_user(kbuf, ubuf, size);if(ret){printk("copy from user failed...\n");return -EIO;}switch(kbuf[0]){/*case '0':gpiod_set_value(desc1, 0);break;*/case '1':gpiod_set_value(desc1, 1);break;/*case '2':gpiod_set_value(desc2, 0);break;*/case '3':gpiod_set_value(desc2, 1);break;/*case '4':gpiod_set_value(desc3, 0);break;*/case '5':gpiod_set_value(desc3, 1);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,.read = mycdev_read,.write = mycdev_write,.release = mycdev_close,
};static int __init mycdev_init(void)
{int ret,i;major = register_chrdev(0, "myled", &fops);if(major<0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功,major=%d\n", major);//根据路径解析设备树节点信息node = of_find_node_by_path("/myleds");if(node == NULL){printk("of_find_node_by_path failed...\n");return -1;}//根据路径解析设备树节点信息node2 = of_find_node_by_path("/myirq");if(node2 == NULL){printk("of_find_node_by_path failed...\n");return -1;}/* //老版//根据设备树结构体信息解析GPIO编号gpiono = of_get_named_gpio(node, "led1", 0);if(gpiono < 0){printk("of_get_named_gpio failed...\n");return -1;}//注册GPIO编号ret = gpio_request(gpiono, NULL);if(ret){printk("gpio_request failed...\n");return -1;}//设置当前GPIO方向为输出gpio_direction_output(gpiono, 0);//点灯gpio_set_value(gpiono, 1);*///根据设备树节点信息解析出软中断号for(i=0;i<MAX;i++){irqno[i]=irq_of_parse_and_map(node2,i);if(irqno[i]==0){printk("irq_of_parse_and_map failed...\n");return -ENOENT;}//注册中断号进内核ret=request_irq(irqno[i],irq_handler,IRQF_TRIGGER_FALLING,irqname[i],(void *)i);if(ret){printk("request_irq failed...\n");return ret;}}//新版//led1,从设备书节点中解析和申请gpio编号,并设置方向为输出(默认低电平LOW)desc1 = gpiod_get_from_of_node(node, "led1", 0, GPIOD_OUT_LOW, NULL);if(IS_ERR(desc1)){printk("#desc1 gpiod_get_from_of_node failed...\n");return PTR_ERR(desc1);}//led2,从设备书节点中解析和申请gpio编号,并设置方向为输出(默认低电平LOW)desc2 = gpiod_get_from_of_node(node, "led2", 0, GPIOD_OUT_LOW, NULL);if(IS_ERR(desc2)){printk("#desc2 gpiod_get_from_of_node failed...\n");return PTR_ERR(desc2);}//led3,从设备书节点中解析和申请gpio编号,并设置方向为输出(默认低电平LOW)desc3 = gpiod_get_from_of_node(node, "led3", 0, GPIOD_OUT_LOW, NULL);if(IS_ERR(desc3)){printk("#desc3 gpiod_get_from_of_node failed...\n");return PTR_ERR(desc3);}return 0;
}static void __exit mycdev_exit(void)
{int i;//灭灯//gpio_set_value(gpiono, 0);gpiod_set_value(desc1, 0);gpiod_set_value(desc2, 0);gpiod_set_value(desc3, 0);//释放申请的GPIO编号//gpio_free(gpiono);gpiod_put(desc1);gpiod_put(desc2);gpiod_put(desc3);//注销中断for(i=0;i<MAX;i++){free_irq(irqno[i], (void *)i);}unregister_chrdev(major, "myled");}module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
相关文章:
使用中断子系统实现对LED灯的控制
中断顶半部:不允许耗时操作 代码流程: 1、基于字符设备驱动的注册(手动/自动) 2、基于设备树文件的自定义完成(myled, myirq) 2、基于GPIO子系统实现led的点亮(流水/测试文件控制) 3、中断子系统操作流程 …...

《爆肝整理》保姆级系列教程python接口自动化(十五)--参数关联接口(详解)
简介 我们用自动化新建任务之后,要想接着对这个新建任务操作,那就需要用参数关联了,新建任务之后会有一个任务的Jenkins-Crumb,获取到这个Jenkins-Crumb,就可以通过传这个任务Jenkins-Crumb继续操作这个新建的任务。 …...

【JDK8】MyBatis源码导入Idea
1.背景 为了更好的将MyBatis的开发设计思想带到日常开发工作,将MyBatis源码导入到本地开发工具中(idea)。我自己在导入的时候碰到几个问题,耽误了自己一点时间,这里我把它们记下来,后边的小伙伴可不要踩我的坑。 Java版本&#x…...

三层交换机DHCP中继
关于中继,我们需要有一个对比。正常情况下我们是不是需要配置单臂路由然后开启DHCP地址池,然就设置网段网关以及DNS。这样的话考验 的其实是命令功底。但是为了方便,我们 可以添加服务器,将这个服务给到服务器去配置,这…...

C++之RALL机制
RALL是Resource acquisition is initialization的缩写,意思是“资源获取即初始化”,其核心思想是利用C对象生命周期的概念来控制程序的资源。它的技术原理很简单,如果希望对某个重要资源进行跟踪,那么创建一个对象,并将…...

回溯算法章末总结
组合问题的特点 (1)abba 选中a之后,就不再选了 (2)找出所有的组合 (长度可以不相等) 组合问题模板 做回溯题步骤 (0)判断问题类型 (1)树状图 …...
【SpringBoot】为异步任务规划线程池
一、线程池的作用 防止资源占用无限的扩张调用过程省去资源的创建和销毁所占用的时间 在上一节中,我们的一个异步任务打开了一个线程,完成后销毁。在高并发环境下,不断的分配新资源,可能导致系统资源耗尽。所以为了避免这个问题…...

SAP ABAP 输出结果带有空格
方法一: 字段内容前增加空格,需使用全角空格,使用半角空格时,ALV显示无效,空格无法显示, 全角与半角的切换方法:shift空格切换, 如下的标记部分,要想通过ALV显示空格&…...
Opengl ES之踩坑记
前因 最近在尝试使用Opengl ES实现一些LUT滤镜效果,在实现这些滤镜效果的时候遇到一些兼容性的坑,踩过这些坑后我希望把这几个坑分享给读者朋友们, 希望同在学习Opengl ES的朋友们能少走弯路。 关于LUT滤镜相关的介绍,也是这个O…...

设计模式第六讲:责任链模式和迭代器模式详解
一. 责任链模式1. 背景在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批…...

K8s 架构简介(一)
一、前言 在开始学习K8s之前,让我们对容器有一个基本的了解 1.1 什么是容器 一个容器镜像是一个可运行的软件包,其中包含了一个完整的可执行程序,包括代码和运行时需要应用、系统库和全部重要设置的默认值。 通过将应用程序本身ÿ…...

xshell6运行报错:由于找不到mfc110u.dll、MSVCR110.dll无法继续执行代码
今天给大家分享一下我刚装完系统遇到得问题,由于新盟的罗建雨【胡巴】老师帮我给电脑加了固态,又重装了系统,因此电脑里面得所有软件需要重装,在我重装的过程中遇到了一个小问题给大家分享一下,如果大家以后遇到也方便解决。 问题: 安装Xshell时电脑系统报错:“由于找…...

Baklib知识库管理平台,协助组织提升知识管理水平
随着信息时代和知识经济时代的到来,企业内部信息资料繁多冗杂,知识管理逐渐成为各大企业的重要工作之一,企业管理者无不感受到巨大的压力,怎么样将知识进行有效的管理,成为一个难点,并且随着信息不断的更迭…...

一文搞懂core-scheduling核心机制
cookie的原理借助于unsigned long型,和refcount_t引用计数器。 32位64位char *4字节8字节unsigned long4字节8字节 数据结构修改 首先看看实现core scheduling功能对数据结构有哪些修改 task_struct struct task_struct{struct rb_node core_node;unsigned long…...

IP地址在金融行业有哪些应用?
中国加入WTO以来经济得到迅速发展,金融行业随着经济发展体系越来越完善。随着西方金融公司和理念的加入中国金融行业开始多样化发展。金融行业在快速发展的同时也引发了许多弊端。如何维护挖掘客户更大需求?如何获取更多优质客户?如何提升网络…...

GT-suite v2016解决许可证过期问题(附新版liscense下载地址)
安装GT-suite v2016时遇到了如图报错的问题。当时的报错找不到了,下图是贴吧相同问题的报错图。 为了解决问题,先根据某网友的如下答复操作: 添加环境变量后仍然有相同报错。 看来需要寻找其他方法。 再尝试着卸载GT-suite v2016,…...
小红书商业笔记与普通笔记区别是什么?小红书笔记有哪几种
主攻单一平台,如何迅速打造爆文。针对软文发布类别的选择,小红书商业笔记与普通笔记区别究竟是什么,今天为大家带来的详细分析,告诉你该如何用最少的成本,做出“爆文”。1、小红书的笔记类型我们都知道,小红…...
DataWhale-统计学习方法打卡Task01
学习教材《统计学习方法(第二版)》李航 统计学习方法(第2版) by...李航 (z-lib.org).pdf https://www.aliyundrive.com/s/maJZ6M9hrTe 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无…...

Java面试——Spring 事务
目录 1.什么是Spring 事务 2.Spring 事务的开启方式 3.Spring事务的实现方式/原理 4.事务传播机制 5.事务隔离级别 6.事务失效的原因 1.什么是Spring 事务 事务在逻辑上是一组操作,要么执行,要不都不执行。 如下: Begin; insert into…...

Python语言零基础入门教程(十九)
Python 异常处理 python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试python程序。 1、异常处理 2、断言(Assertions) python标准异常 什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生&…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...