【linux内核中断】

1.linux内核中断子系统相关的API

解析中断的相关设备树节点信息

of_find_compatible_node

根据解析的中断信息获取软中断号

irq_of_parse_and_map(struct device_node *dev,int index)

参数:dev中断对应的设备树节点指针 index:当前中断 对应值的索引号

返回值:成功返回软中断号,失败返回0

注册中断

request_irq(unsigned int irq,irq_handler_t handler,unsigned long flags,const char *name,void *dev)

参数:irq:当前中断的软中断号

           handler:中断处理函数的函数指针

           flags:设置中断的触发方式

           name:当前中断名字

           dev:传递给中断处理程序的参数,也是当前中断对应的irqatction的key值

注销中断

void *free_irq(unsigned int irq,void *dev_id)

参数:

        irq:要注销的中断对应的软中断号

        dev_id:request_irq最后一个参数的数值,一定要写的和注册时的一样,不然会报错

6.中断底半部

中断顶半部:主要处理一些紧急,不耗时的任务

中断底半部:主要处理一些不紧急,耗时的任务

tasklet

tasklet机制是基于软中断实现的一种底半部的机制,但是相比较于软中断,tasklet没有最大数量的限制

驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
int number = 0;
struct device_node *dnode;
unsigned int key_irqno[3];
struct cdev *cdev;
unsigned int major;
unsigned int minor;
dev_t devno;
unsigned int condition = 0;
struct class *cls;
struct device *dev;
// 定义等待队列头
wait_queue_head_t wq_head;
char kbuf[128] = {0};
struct device_node *dnode;
unsigned int gpiono;
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 *lof)
{// 将准备好的硬件数据拷贝到用户空间int ret = copy_to_user(ubuf, (void *)number, size);if (ret){printk("copy_to_user err\n");return ret;}return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{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,
};
irqreturn_t key_handler(int irq, void *dev)
{// 根据dev的数值的不同来区分不同的按键int which = (int)dev;switch (which){case 0:number = 0;if (gpio_get_value(gpiono))// 亮灯gpio_set_value(gpiono, 1);elsegpio_set_value(gpiono, 0);printk("key1 interrupt\n");break;case 1:number = 1;if (gpio_get_value(gpiono))// 亮灯gpio_set_value(gpiono, 1);elsegpio_set_value(gpiono, 0);printk("key2 interrupt\n");break;case 2:number = 2;if (gpio_get_value(gpiono))// 亮灯gpio_set_value(gpiono, 1);elsegpio_set_value(gpiono, 0);printk("key3 interrupt\n");break;default:break;}return IRQ_HANDLED;
}
static int __init mycdev_init(void)
{// 注册字符设备驱动major = register_chrdev(0, "MYchrdev", &fops);if (major < 0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功major=%d\n", major);// 向上提交目录信息cls = class_create(THIS_MODULE, "MYcdev");if (IS_ERR(cls)){printk("向上提交目录信息失败\n");return -PTR_ERR(cls);}printk("向上提交目录信息成功\n");// 向上提交设备信息dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "MYcdev%d", 0);if (IS_ERR(dev)){printk("向上提交设备节点失败\n");return -PTR_ERR(cls);}printk("向上提交设备节点信息成功\n");// 通过设备树节点名字解析设备树结点dnode = of_find_compatible_node(NULL, NULL, "hqyj,myirq");if (dnode == NULL){printk("解析设备树节点信息失败\n");return -ENXIO;}printk("解析设备树节点信息成功\n");// 获取软中断号int i;for (i = 0; i < 3; i++){key_irqno[i] = irq_of_parse_and_map(dnode, i);if (!key_irqno[i]){printk("解析按键的设备树节点失败\n");return -ENXIO;}printk("解析按键的设备树节点成功\n");// 注册中断int ret;ret = request_irq(key_irqno[i], key_handler, IRQF_TRIGGER_FALLING, "key", (void *)i);if (ret < 0){printk("注册中断失败\n");return -1;}printk("注册中断成功\n");}// 解析LED设备树节点dnode = of_find_node_by_path("/leds");if (dnode == NULL){printk("解析设备树节点失败\n");return -ENXIO;}printk("解析设备树节点成功\n");// 获取GPIO编号gpiono = of_get_named_gpio(dnode, "led1-gpio", 0);if (gpiono < 0){printk("gpio编号解析失败\n");return -ENXIO;}printk("解析gpio编号成功%d\n", gpiono);// 申请gpio编号int ret;ret = gpio_request(gpiono, NULL);if (ret){printk("申请gpio编号失败\n");return -1;}printk("申请gpio编号成功\n");// 设置为输出模式gpio_direction_output(gpiono, 0);return 0;
}
static void __exit mycdev_exit(void)
{int i;for (i = 0; i < 3; i++)free_irq(key_irqno[i], (void *)i);gpio_free(gpiono);device_destroy(cls, MKDEV(major, i));// 销毁目录信息class_destroy(cls);// 字符设备驱动的注销unregister_chrdev(major, "MYchrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

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

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

相关文章

力扣-哈希-字母异位词分组

题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat&q…

java八股文面试[多线程]——什么是线程安全

对线程安全的理解 总结&#xff1a;一个进程内的多个线程同时访问堆内存。 知识来源&#xff1a; 【并发与线程】对线程安全的理解_哔哩哔哩_bilibili

nginx配置SSL证书配置https访问网站 超详细(附加配置源码+图文配置教程)

最近在阿里云上入手了一台云服务器&#xff0c;准备搭建一套java程序&#xff0c;在Nginx配置SSL证书时&#xff0c;配上之后前端可以正常以https的方式打开&#xff0c;但是访问不到后端&#xff0c;自己也是明明知道是Niginx配置的问题&#xff0c;但就不知道错哪了&#xff…

VS Code插件汇总

插件 Basic Chinese(Simplified) Language Pack C/C C/C CMake Tools C/C Extension Pack Web Open in browser Microsoft Edge Tool Linux WSL Tool AWS Toolkit Bito AI Code Assistant CursorCode TabNine IntelliCode Kite

【大模型AIGC系列课程 2-3】动手为ChatGPT打造第二大脑

文本向量的应用 one-hot 文本向量 !pip install jiebaimport jieba # 中文分词包text = 6月27日,世界经济论坛发布了《2023年10大新兴技术》报告。重点介绍了在未来3—5年对全球经济、工作、生活、医疗等产生积极影响的创新技术。其中,生成式AI首次入选并排名第2位。世界经…

9.4 集成功率放大电路

OTL、OCL 和 BTL 电路均有各种不同输出功率和不同电压增益的集成电路。应当注意&#xff0c;在使用 OTL 电路时&#xff0c;需外接输出电容。为了改善频率特性&#xff0c;减小非线性失真&#xff0c;很多电路内部还引入深度负反馈。这里以低频功放为例。 一、集成功率放大电路…

创邻科技张晨:图数据库,激活数据要素的新基建

“数据经济时代&#xff0c;数据要素产业链的各细分领域均蕴含机遇&#xff0c;图技术作为网络协同和数据智能的底层发动机&#xff0c;将深度掘金数字中国价值潜能”。 8月22日&#xff0c;在2023中国&#xff08;南京&#xff09;国际软件产品和信息服务交易博览会的信息技术…

Selenium 遇见伪元素该如何处理?

问题发生 在很多前端页面中&#xff0c;大家会见到很多&#xff1a;:before、::after 元素&#xff0c;比如【百度流量研究院】&#xff1a; 比如【百度疫情大数据平台】&#xff1a; 以【百度疫情大数据平台】为例&#xff0c;“累计确诊”文本并没有显示在 HTML 源代码中&am…

【力扣周赛】第360场周赛

【力扣周赛】第360场周赛 8015.距离原点最远的点题目描述解题思路 8022. 找出美丽数组的最小和题目描述解题思路 8015.距离原点最远的点 题目描述 描述&#xff1a;给你一个长度为 n 的字符串 moves &#xff0c;该字符串仅由字符 ‘L’、‘R’ 和 ‘_’ 组成。字符串表示你在…

Vue实例挂载的过程

一、思考 我们都听过知其然知其所以然这句话 那么不知道大家是否思考过new Vue()这个过程中究竟做了些什么&#xff1f; 过程中是如何完成数据的绑定&#xff0c;又是如何将数据渲染到视图的等等 二、分析 首先找到vue的构造函数 源码位置&#xff1a;src\core\instance\…

【项目实战典型案例】05.前后端分离的好处(发送调查问卷)

目录 一、背景二、思路三、过程1、主要的业务逻辑2、解决问题的思路 四、总结五、面向对象的好处 一、背景 以下流程图是给用户发送调查问的整体流程&#xff0c;将不必要的业务逻辑放到前端进行处理。这样导致逻辑混乱难以维护。前后端分离的其中一个目的是将功能的样式放在了…

在x86机器上的Docker运行arm64容器

1. 引言 工作中常用电脑主机CPU为x86架构&#xff0c;有时由于产品需要&#xff0c;我们需要编译aarch64架构的SDK或者应用程序供使用或者测试。 一种比较快捷的方式是使用aarch64的CPU构建相应操作系统&#xff0c;实现真机运行。但在无arm架构CPU环境下&#xff0c;我们可否…

AODV代码实现详解——原理与源码分析(一)

首先来几个标准参考&#xff1a; RFC 3561 RFC 3561 中文翻译 一个博客 挺好的另一个博客 事件&#xff1f; 字段长度&#xff1f; 事件驱动 各种定时器 状态转移图&#xff1f; AODV协议 基本概念 AODV&#xff08;Ad hoc On-Demand Distance Vector&#xff09;是一种基于…

请你说说json 序列化功能

JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。JSON基于JavaScript编程语言&#xff0c;是一种文本格式&#xff0c;完全独立于语言。 JSON序列化是将复杂的对象结构…

HLS 后端示例

更多 TVM 中文文档可访问 →Apache TVM 是一个端到端的深度学习编译框架&#xff0c;适用于 CPU、GPU 和各种机器学习加速芯片。 | Apache TVM 中文站 TVM 支持带有 SDAccel 的 Xilinx FPGA 板&#xff0c;接下来介绍如何将 TVM 部署到 AWS F1 FPGA 实例。 备注&#xff1a;此功…

windows linux 都可执行的脚本 bat, shell 共存

核心, 执行一行解析一行 windows:执行的地方进行解析, 可以任意跳转执行; bash从上往下解析执行; 一行行解析发现语法错误; 差异: windows可以部分不解析; linux需要从上往下解析合法; 总结:linux, windows可以一上一下共存 # linux code# windows code 关键: 脚本解析的差…

Java进阶篇--泛型

前言 Java 泛型&#xff08;generics&#xff09;是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制&#xff0c;该机制允许程序员在编译时检测到非法的类型。它允许在定义类、接口和方法时使用类型参数。这种技术使得在编译期间可以使用任何类型&#xff0c;而…

【活动】怎么维护电脑?

无论是学习还是工作&#xff0c;电脑都是IT人必不可少的重要武器&#xff0c;一台好电脑除了自身配置要经得起考验&#xff0c;后期主人对它的维护也是决定它寿命的重要因素&#xff01; 其实这是个伪命题&#xff0c;就像穿衣一样&#xff0c;有的人喜欢干净整洁&#xff0c;…

门禁系统忘记登入密码,现在更换电脑如何迁移旧电脑门禁系统的数据

环境&#xff1a; ivms-4200 v3.10.0.6_c 问题描述&#xff1a; 门禁系统忘记登入密码,现在更换电脑如何迁移旧电脑门禁系统的数据&#xff0c;旧电脑记住密码&#xff0c;忘了密码和密保了 解决方案&#xff1a; 1.前往海康官网下载4200客户端&#xff0c;在新电脑上安装 …