驱动开发(四):Linux内核中断
驱动开发系列文章:
驱动开发(一):驱动代码的基本框架
驱动开发(二):创建字符设备驱动
驱动开发(三):内核层控制硬件层
驱动开发(四):Linux内核中断
目录
简介
中断原理
函数实现
注册中断
注销中断
按键中断实验
驱动代码
常见问题
解决方法
关于按键的抖动
简介
Linux内核中断是一种控制传递机制,用于处理硬件设备的事件和异常。当硬件设备发生特定事件时,例如数据传输完成、错误发生或设备准备就绪,它会向CPU发送中断信号,以引起CPU的注意。
Linux内核中断分为两种类型:外部中断和内部中断。外部中断由外部硬件设备触发,如键盘按键、鼠标点击或网络数据包到达。内部中断由CPU内部产生,如除法错误、缺页异常或系统调用。
中断处理程序是用来响应和处理中断的函数。当中断发生时,CPU会暂时停止当前正在执行的任务,并跳转到相应的中断处理程序执行。中断处理程序根据中断的类型和优先级,执行相应的操作以处理中断事件。
Linux内核提供了一个中断向量表(Interrupt Vector Table),其中包含了所有中断的处理程序的入口地址。当中断发生时,CPU会根据中断号在中断向量表中查找相应的处理程序的地址,并将控制权转移给这个地址。
在Linux内核中,中断有优先级,较高优先级的中断可以打断正在运行的较低优先级中断,这被称为中断抢占。Linux内核通过中断处理程序的优先级和抢占策略来管理中断的响应和处理。
中断是Linux内核实现设备驱动和处理硬件事件的重要机制。它能够提高系统的并发性和响应性,有效地处理多种硬件设备的事件和异常。
中断原理
Linux内核中断的原理主要涉及硬件、中断控制器和中断处理程序的协作工作。
硬件触发中断:当硬件设备发生特定事件时,例如数据传输完成、错误发生或设备准备就绪,它会向CPU发送中断信号。这个中断信号会被送到中断控制器。
中断控制器:中断控制器是硬件设备负责管理和传递中断信号的组件。它负责接收中断信号,确定中断的类型和优先级,并通过中断向量表将控制权传递给相应的中断处理程序。
中断处理程序:中断处理程序是用来响应和处理中断的函数。当中断发生时,CPU会跳转到相应的中断处理程序的入口地址执行。中断处理程序根据中断的类型和优先级,执行相应的操作以处理中断事件。
中断处理过程:当中断发生时,CPU会先保存当前的执行环境(包括寄存器状态、程序计数器等),然后根据中断号在中断向量表中查找相应的中断处理程序的入口地址。中断处理程序会执行特定的操作,处理中断事件。处理完成后,CPU会恢复之前保存的执行环境,并继续执行被中断的任务。
中断抢占:在Linux内核中,中断有优先级,较高优先级的中断可以打断正在运行的较低优先级中断,这被称为中断抢占。中断抢占能够保证紧急事件的优先处理,并提高系统的并发性和响应性。
总结来说,Linux内核中断的原理是通过硬件设备触发中断信号,中断控制器将中断信号传递给CPU,CPU根据中断号在中断向量表中查找对应的中断处理程序,并执行特定的操作来处理中断事件。中断抢占能够保证紧急事件的优先处理,并提高系统的并发性和响应性。
先找到IRQ的标签,然后跳转,跳转时这个名字是写死的(handle_irq),在handle_irq里定义一个数组,irq_desc[],数组的每一个成员变量里存了结构体,irq_xxx。在结构体里面有个函数指针,这个指针指向了我们函数的名字。数组的下标和中断号有关系,这里是中断号,但是是软中断号。
软中断号是linux内核给分配的中断号,是内核为了兼容各种芯片,而设计的。这里兼容是通过映射实现的,我们不同的板子根据映射关系,使用中断号得到软中断号。
函数实现
注册中断
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
功能:注册中断
参数:@irq : 软中断号 gpio的软中断号 软中断号 = gpio_to_irq(gpio号);gpio号 = m*32+n m:哪一组 A B C D E 0 1 2 3 4 n:组内的序号例如:GPIOA28的gpio号 = 0*32+28 = 40@handler: 中断的处理函数irqreturn_t (*irq_handler_t)(int irqno, void *dev);IRQ_NONE //中断没有处理完成IRQ_HANDLED //中断正常处理完成@flags :中断的触发方式#define IRQF_DISABLED 0x00000020 //快速中断#define IRQF_SHARED 0x00000080 //共享中断#define IRQF_TRIGGER_RISING 0x00000001//上升沿#define IRQF_TRIGGER_FALLING 0x00000002//下降沿#define IRQF_TRIGGER_HIGH 0x00000004//高电平#define IRQF_TRIGGER_LOW 0x00000008//低电平@name :名字 cat /proc/interrupts@dev :向中断处理函数中传递参数 ,如果不想传写个NULL就行返回值:成功0,失败返回错误码
共享中断(中断的接口较少,但是器件都想要中断,那管脚需要外接两个,寄存器里面有中断状态标志位,看中断状态标志位有没有置位。一个口不可以链接两个按键,按键没办法区分)
注销中断
oid free_irq(unsigned int irq, void *dev_id)
功能:注销中断
参数:@irq :软中断号@dev_id:向中断处理函数中传递的参数 ,如果上面写的NULL,这里就写NULL
按键中断实验
1、 查看实物,找到按键(丝印)
2、 去地板原理图(网络标号----->芯片引脚)

GPIOB8--------->gpio号=40

GPIOB16--------->gpio号=48

驱动代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>#define GPIONO(m, n) m * 32 + n //计算gpio号
#define GPIO_B8 (GPIONO(1, 8))
#define GPIO_B16 (GPIONO(1, 16))
int gpiono[] = {GPIO_B8, GPIO_B16}; //数组内存入两个按键的软中断号
char *name[]={"gpio_it_8","gpio_it_16"}; //随便定义,用于区分int ret,i;//中断处理函数
irqreturn_t handler(int irqno, void *dev)
{if(irqno == gpio_to_irq(GPIO_B8)){printk(KERN_ERR "+++++++++++++\n");}if(irqno == gpio_to_irq(GPIO_B16)){printk(KERN_ERR "-------------\n");}return IRQ_HANDLED;
}static int __init hello_init(void)
{
//循环注册中断 gpio_to_irq()for (i = 0; i < sizeof(gpiono) / sizeof(int); i++){ret = request_irq(gpio_to_irq(gpiono[i]), handler, IRQF_TRIGGER_FALLING,name[i], NULL);if (ret != 0){printk(KERN_ERR "%s request irq err\n",name[i]);return ret;}}return 0;
}
static void __exit hello_exit(void)
{
//循环注销中断for (i = 0; i < sizeof(gpiono) / sizeof(int); i++){free_irq(gpio_to_irq(gpiono[i]), NULL);}
}module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
常见问题
驱动安装时报错:
insmod: can't insert 'farsight_irq.ko': Device or resource busy
解决方法

154: GPIO nxp-keypad
说明中断号已经被占用了,要在内核中将占用中断号的驱动删掉
2、在虚拟机中,内核顶层目录上执行 grep "nxp-keypad" * -nR

arch/arm/mach-s5p6818/include/mach/devices.h:48:#define DEV_NAME_KEYPAD "nxp-keypad"
3、执行 grep "DEV_NAME_KEYPAD" * -nR

找到驱动文件的名字是nxp_io_key.c
4、cd drivers/input/keyboard/
5、vi Makefile
6、找到由nxp_io_key.o生成的目标文件KEYBOARD_NXP_KEY
7、make menuconfig


8、make uImage 重新编译内核
9、cp arch/arm/boot/uImage ~/tftpboot 将内核放到TFTP下
关于按键的抖动

明明只按了一次按键,却打印了多条信息
所有的机械元件都会有抖动问题

主要原因不是手抖,而是硬件自身的抖动(输入的机械元件才会有抖动)
最好是使用定时器的方式消抖

定时器消抖的原理:
主程序触发中断-》在按键中断服务程序里开启定时器-》在定时器中断里实现按键中断操作
好处:避免在中断里面使用延时函数,增加CPU的执行效率
相关文章:
驱动开发(四):Linux内核中断
驱动开发系列文章: 驱动开发(一):驱动代码的基本框架 驱动开发(二):创建字符设备驱动 驱动开发(三):内核层控制硬件层 驱动开发(四…...
btrace:binder_transaction+eBPF+Golang实现通用的Android APP动态行为追踪工具
一、简介: 在进行Android恶意APP检测时,需要进行自动化的行为分析,一般至少包括行为采集和行为分析两个模块。其中,行为分析有基于规则、基于机器学习、基于深度学习甚至基于大模型的方案,各有各的优缺点,不…...
C# OCCT Winform 界面搭建
目录 1.创建一个WInform项目 2.代码总览 代码解析 3.添加模型到场景 4.鼠标交互 1.创建一个WInform项目 2.代码总览 using Macad.Occt.Helper; using Macad.Occt; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Remoting.Co…...
System.Dynamic.ExpandoObject的使用说明
官方文档 ExpandoObject 类 (System.Dynamic) | Microsoft Learn https://learn.microsoft.com/zh-cn/dotnet/api/system.dynamic.expandoobject?viewnet-8.0 System.Dynamic.ExpandoObject 类 - .NET | Microsoft Learn https://learn.microsoft.com/zh-cn/dotnet/fundame…...
adb之ps命令用法
目录 前言一、命令参数二、输出结果含义 前言 在adb shell终端,输入 ps,可查看手机当前所有的进程状态,其中ps的英文全称是Process Status。 ps命令对于分析系统异常情况时都是必备的技能,需要通过这个简单命令来查看系统真实的状…...
Ubuntu-24.04-live-server-amd64安装界面中文版
系列文章目录 Ubuntu安装qemu-guest-agent Ubuntu-24.04-live-server-amd64启用ssh Ubuntu乌班图安装VIM文本编辑器工具 文章目录 系列文章目录前言一、准备工作二、开始安装三、测试效果总结 前言 Centos结束,转战Ubuntu。我之所以写这篇文章,是因为我…...
Git的3个主要区域
一般来说,日常使用只要记住下图6个命令,就可以了。但是熟练使用,恐怕要记住60~100个命令。 下面是我整理的常用 Git 命令清单。几个专用名词的译名如下。 Workspace:工作区 Index / Stage:暂存区 Reposito…...
【操作系统】操作系统实验02-生产者消费者程序改进
1. 说明文档中原有程序实现的功能、实现方法。(用语言、程序流程图、为原有程序添加注释等方式均可) 1.//const.h 2.//定义宏变量 3.#ifndef CONST_H 4.#define CONST_H 5. 6.#define TRUE 1 7.#define FALSE 0 8.#define ERROR 0 9.#define OVERFLOW -…...
TCP协议是安全的吗?
不安全 虽然 TCP 提供了一种可靠且高效的数据传输方式,但它不提供任何加密或身份验证机制来保护数据。因此,传输的数据可能会被未经授权的用户拦截和读取,而且其真实性无法验证。 因此,为了确保 TCP 通信的安全,必须…...
c语言回顾-结构体(2)
前言 前面讲了结构体的概念,定义,赋值,访问等知识,本节内容小编将讲解结构体的内存大小的计算以及通过结构体实现位段,话不多说,直接上干货!!! 1.结构体内存对齐 说到计…...
Prometheus常见exporter安装部署
Prometheus常见exporter安装部署 在稳定性环境的监控当中需要收集各种各样的数据,这样的数据收集是通过各种exporter进行的,在这里我们进行最常用稳定性数据的收集exporter安装部署介绍。 node_exporter安装部署 node_exporter主要监控服务器本身的一…...
DGit的使用
将Remix连接到远程Git仓库 1.指定克隆的分支和深度 2.清理,如果您不在工作区上工作,请将其删除或推送至 GitHub 或 IPFS 以确保安全。 为了进行推送和拉取,你需要一个 PAT — 个人访问令牌 当使用 dGIT 插件在 GitHub 上推送、拉取、访问私…...
ElasticSearch学习篇13_《检索技术核心20讲》进阶篇之LSM树
背景 学习极客实践课程《检索技术核心20讲》https://time.geekbang.org/column/article/215243,文档形式记录笔记。 内容 磁盘和内存数据读取特点 工业界中数据量往往很庞大,比如数据无法全部加载进内存,无法支持索引的高效实时更新&…...
简单好用的C++日志库spdlog使用示例
文章目录 前言一、spdlog的日志风格fmt风格printf风格 二、日志格式pattern三、sink,多端写入四、异步写入五、注意事项六、自己封装了的代码usespdlog.h封装代码解释使用示例 前言 C日志库有很多,glog,log4cpp,easylogging, eas…...
python 方法运行计时装饰模式实现
在代码开发过程中,需要记录方法的执行时间,每个方法都硬代码也可以实现,但是不是最好的方式,考虑到设计模式和模版代码,通过装饰模式实现方法运行计时 在Python中,装饰器可以接受参数,这样可以…...
【权威出版/投稿优惠】2024年水利水电与能源环境科学国际会议(WRHEES 2024)
2024 International Conference on Water Resources, Hydropower, Energy and Environmental Science 2024年水利水电与能源环境科学国际会议 【会议信息】 会议简称:WRHEES 2024 大会时间:点击查看 截稿时间:点击查看 大会地点:…...
阿赵UE引擎C++编程学习笔记——场景加载和切换
大家好,我是阿赵。 继续学习UE引擎,这次来学习一下切换和加载场景的各种做法。 一、 蓝图实现 1、 切换关卡 所谓切换关卡,就是从当前关卡进入到一个新的关卡, 旧关卡的数据将会被放弃。进入新的关卡后,将会执行…...
【LLM之RAG】RAFT论文阅读笔记
研究背景 论文针对的主要问题是如何将预训练的大型语言模型(LLMs)适应特定领域的检索增强生成(RAG)。这些模型通常在广泛的文本数据上进行预训练,已经表现出在广义知识推理任务上的优越性能。然而,在特定领…...
【Android】使用Binder(AIDL)实现利用自定义Bean进行的进程间通信(二)
项目前置 这是我之前写的关于Binder的一些知识点和使用基本数据类型在通信的文章,感兴趣的可以看一下: Binder(一)Binder的介绍和AIDL使用Binder的实例 项目目标 在两个APP之间进行数据传递,使用Android推荐的Binder通讯&#…...
HTTP中get与post的区别?在传输数据类型上有什么区别?【面试】
HTTP中的GET和POST是两种最常见的请求方法,它们在数据传输和使用场景上有一些关键的区别: GET请求: 数据传输方式:GET请求将数据附加在URL之后,形成查询字符串(namevalue的形式),数…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
