使用中断子系统实现对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标准异常 什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生&…...
重生之我是赏金猎人-SRC漏洞挖掘(一)-某SRC测试系统无脑Getshell
0x01 前言 https://github.com/J0o1ey/BountyHunterInChina 欢迎大佬们点个star 0x02 资产收集到脆弱系统 在某src挖掘过程中,本人通过ssl证书对域名资产进行了收集,通过计算域名对应ip段的权重 整理出其C段资产,进行了批量目录扫描 查看…...
Sciter 结合 PReact 实现组件公共逻辑抽离
Sciter 结合 PReact 实现组件公共逻辑抽离 下面例子是获取鼠标移动位置,将这部分逻辑进行抽离 一、使用高阶组件抽离公共逻辑 import {Component } from ./preact.js; export const HOCFactory = (Component) => {class HOC...
OpenTracing协议规范链接
一、官网链接 OpenTracing specificationhttps://opentracing.io/specification/不过目前OpenTracing项目已归档,不再维护。需要参考OpenTelemetry官网链接 Migrating from OpenTracing | OpenTelemetryBackward compatibility with OpenTracing has been a prior…...
金三银四面试必看,自动化测试如何解决日志问题
前言 前几天在员群里,有同学问了一个自动化测试实践中遇到的问题: 持续集成的自动化用例很多,测试环境日志level为debug,日志量大概40G/每天,定位问题时日志查询很慢,该怎么解决? 这个问题可…...
微信怎么开小店?【企业商家微信开店】
企业商家入局微信做营销已经是经营规划中必须做的一件事了,对于企业商家来说,最简单直接的方式就是开一个微信小店,然后通过自己宣传推广来在微信小店中成商品。那么企业商家在微信怎么开小店呢?下面内容分享给想在微信开店的企业…...
Java 中FastJson的使用【吃透FastJson】
如果不了解JSON格式,建议先看下:JSON数据格式【学习记录】 JSON序列化、反序列化JavaBean的框架有很多,最常见的Jackson、阿里巴巴开源的FastJson、谷歌的GSON、apache提供的json-lib等,下面我们主要来熟悉一下:Java语…...
Redis5.0集群搭建
Redis集群教程 此文重在介绍 Redis5.0 三主三从集群安装,无复杂难懂的概念,若想深入了解集群原理请参考Redis集群规范。 Redis集群介绍 Redis Cluster 提供一种 Redis 安装方式:数据自动在多个 Redis 节点间分片。 Redis Cluster 提供一定…...
继企业级信息系统开发学习1.1 —— Spring配置文件管理Bean
骑士救美计划采用构造方法注入属性值1、创建救美任务类2、创建救美骑士类2、创建救美骑士类3、创建旧救美骑士测试类3、配置救美骑士Bean5、创建新救美骑士测试类采用构造方法注入属性值 1、创建救美任务类 在net.huawei.spring.day01包里创建RescueDamselQuest类 Rescue Da…...
Web 容器、HTTP 服务器 、Servlet 容器区别与联系
首先浏览器发起 HTTP 请求,像早期的时候只会请求一些静态资源,这时候需要一个服务器来处理 HTTP 请求,并且将相应的静态资源返回。 这个服务器叫 HTTP 服务器。 简单点说就是解析请求,然后得知需要服务器上面哪个文件夹下哪个名字…...
eBPF 进阶: 内核新特性进展一览
Linux 内核在 2022 年主要发布了 5.16-5.19 以及 6.0 和 6.1 这几个版本,每个版本都为 eBPF 引入了大量的新特性。本文将对这些新特性进行一点简要的介绍,更详细的资料请参考对应的链接信息。总体而言,eBPF 在内核中依然是最活跃的模块之一&a…...
网络营销工作/sem优化软件选哪家
条款7 预先准备好内存不够的情况 operator new在无法完成内存分配请求时会抛出异常(老的编译器返回0); C常用的做法, 定义一个类型无关的宏来分配内存并检查是否成功; 123#define NEW(PTR, TYPE) \try { (PTR) new TYPE; } \catch (std::bad_alloc&) { assert(0); }>…...
济南网站建设云华互动/凡科建站靠谱吗
先来说一下对异步和同步的理解:同步调用:调用方在调用过程中,持续等待返回结果。异步调用:调用方在调用过程中,不直接等待返回结果,而是执行其他任务,结果返回形式通常为回调函数。其实…...
邢台住房和城乡建设部网站/seo培训赚钱
场景 github看到一个Wxpuhser的项目,想知道它的使用场景,如何使用,以及由此引申出来的思考 项目中运行一个任务,对于执行结果需要及时接收到信息,有哪几种备选方案? 方式一:发短信。集成第三方提供的短信接口&…...
湖南长沙网站建设/山东潍坊疫情最新消息
构建高性能的web站点需要考虑很多方面,我们在这了解一下其中一项---------数据库扩展,希望能够让没有接触过这方面知识的朋友对数据库扩展有个认识吧。 随着用户数量的不断增加,数据库将面临着巨大的增删改查,即便我们将sql语句优…...
济南地铁建设/googleseo服务公司
[sizex-large][colorred]Java集合框架之fastutil [/color][/size][url]http://rensanning.iteye.com/blog/1548162[/url] fastutil扩展了 Java集合框架,通过提供特定类型的map、set、list和queue,以及小内存占用、快速访问和插入;也提供大&am…...
做的网站不能放视频/b站推广网站2022
560. 和为 K 的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回该数组中和为 k 的连续子数组的个数。 示例 1: 输入:nums [1,1,1], k 2 输出:2 示例 2: 输入:nums [1,2,3], k 3 输出&am…...