驱动开发(四):Linux内核中断

 驱动开发系列文章:
                驱动开发(一):驱动代码的基本框架    
                驱动开发(二):创建字符设备驱动
                驱动开发(三):内核层控制硬件层  

                驱动开发(四):Linux内核中断

目录

简介

中断原理

函数实现

注册中断

注销中断 

按键中断实验

驱动代码 

常见问题

解决方法

关于按键的抖动


简介

Linux内核中断是一种控制传递机制,用于处理硬件设备的事件和异常。当硬件设备发生特定事件时,例如数据传输完成、错误发生或设备准备就绪,它会向CPU发送中断信号,以引起CPU的注意。

Linux内核中断分为两种类型:外部中断和内部中断。外部中断由外部硬件设备触发,如键盘按键、鼠标点击或网络数据包到达。内部中断由CPU内部产生,如除法错误、缺页异常或系统调用。

中断处理程序是用来响应和处理中断的函数。当中断发生时,CPU会暂时停止当前正在执行的任务,并跳转到相应的中断处理程序执行。中断处理程序根据中断的类型和优先级,执行相应的操作以处理中断事件。

Linux内核提供了一个中断向量表(Interrupt Vector Table),其中包含了所有中断的处理程序的入口地址。当中断发生时,CPU会根据中断号在中断向量表中查找相应的处理程序的地址,并将控制权转移给这个地址。

在Linux内核中,中断有优先级,较高优先级的中断可以打断正在运行的较低优先级中断,这被称为中断抢占。Linux内核通过中断处理程序的优先级和抢占策略来管理中断的响应和处理。

中断是Linux内核实现设备驱动和处理硬件事件的重要机制。它能够提高系统的并发性和响应性,有效地处理多种硬件设备的事件和异常。

中断原理

Linux内核中断的原理主要涉及硬件、中断控制器和中断处理程序的协作工作。

  1. 硬件触发中断:当硬件设备发生特定事件时,例如数据传输完成、错误发生或设备准备就绪,它会向CPU发送中断信号。这个中断信号会被送到中断控制器。

  2. 中断控制器:中断控制器是硬件设备负责管理和传递中断信号的组件。它负责接收中断信号,确定中断的类型和优先级,并通过中断向量表将控制权传递给相应的中断处理程序。

  3. 中断处理程序:中断处理程序是用来响应和处理中断的函数。当中断发生时,CPU会跳转到相应的中断处理程序的入口地址执行。中断处理程序根据中断的类型和优先级,执行相应的操作以处理中断事件。

  4. 中断处理过程:当中断发生时,CPU会先保存当前的执行环境(包括寄存器状态、程序计数器等),然后根据中断号在中断向量表中查找相应的中断处理程序的入口地址。中断处理程序会执行特定的操作,处理中断事件。处理完成后,CPU会恢复之前保存的执行环境,并继续执行被中断的任务。

  5. 中断抢占:在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

解决方法

1、在开发板执行
cat /proc/interrupts

146: GPIO nxp-keypad

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

drivers/input/keyboard/nxp_io_key.c:324: .name = DEV_NAME_KEYPAD,

找到驱动文件的名字是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的执行效率

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024FIC决赛

容器密码&#xff1a;2024Fic~Competition~Finals杭州&Powered~By~HL! 案件背景: 2023年3月15日凌晨,受害人短视频平台上看到一段近期火爆的交通事故视频&#xff0c;留言后有人通过私信联系&#xff0c;称有一个赚大钱的机会&#xff0c;该人自称李某&#xff0c;提议让…

如何通过抖音自动评论精准获客实现业务增长?这些方法值得一试!

在当今竞争激烈的商业环境中&#xff0c;企业若想脱颖而出&#xff0c;就必须掌握精准获客的艺术。精准获客&#xff0c;即通过精确的市场定位和营销策略&#xff0c;吸引并保留最有可能成为客户的目标群体。它不仅能提高转化率&#xff0c;还能有效降低营销成本&#xff0c;是…

实况:老菜鸟自力更生从零开始重学spring目标是画出一张唬人大图(二、源码下载编译)

前情提要&#xff1a;调试前的基础知识梳理 速览 “Spring”包含哪些东西源码下载源码编译1、编译工具选择&#xff1a;gradle2、使用gradle编译spring并导入idea预编译spring-oxm导入IDEA确认合适的jdk版本排除spring-aspects模块 开始调试 “Spring”包含哪些东西 可以明确的…

LVS负载均衡:理解IPVS和IPVSADM的内部工作原理

LVS 负载均衡工作模式 LVS&#xff08;Linux Virtual Server&#xff09; 共有三种工作模式&#xff1a;DR、Tunnel、NAT。 DR&#xff08;Direct Routing&#xff09;&#xff1a; 技术原理&#xff1a;DR模式下&#xff0c;LVS调度器接收到请求后&#xff0c;直接通过MAC地址…

Kali中安装和使用docker的学习笔记

一、常见命令 ctrl 、shift、 &#xff1a; 窗口变大&#xff1b; ctrl 、- &#xff1a;窗口变小&#xff1b; ctrl L&#xff1a; 清屏 &#xff1b; sudo su : 切换root 用户&#xff1b; ip addr / ifconfig: 获取IP地址&#xff1b; systemctl start ssh…

探索Python的多媒体解决方案:ffmpy库

文章目录 探索Python的多媒体解决方案&#xff1a;ffmpy库一、背景&#xff1a;数字化时代的多媒体处理二、ffmpy&#xff1a;Python与ffmpeg的桥梁三、安装ffmpy&#xff1a;轻松几步四、ffmpy的五项基本功能1. 转换视频格式2. 调整视频质量3. 音频转换4. 视频截图5. 视频合并…

Mybatis框架中结果映射resultMap标签方法属性收录

Mybatis框架中结果映射resultMap标签收录 在MyBatis框架中&#xff0c;resultMap 是一种强大的机制&#xff0c;用于将数据库结果集映射到Java对象上。它允许你定义如何将查询结果中的列映射到Java对象的属性上&#xff0c;尤其是当数据库表的字段名与Java对象的属性名不一致时…

【太原理工大学】软件系统安全—分析题

OK了&#xff0c;又是毫无准备的一场仗&#xff0c;我真是ありがとうございます 凸^o^凸 根据前几年传下来的信息&#xff0c;所谓“分析”&#xff0c;就是让你根据情节自行设计&#xff0c;例如如何设计表单等&#xff0c;这类多从实验中出&#xff0c;王老师强调好好做实验一…

自然抽样和平顶抽样

自然抽样和平顶抽样是两种信号处理和采样技术&#xff0c;它们在音频信号处理、信号重建以及数字信号处理中有着不同的应用。 1. 自然抽样&#xff08;也称为理想抽样或无失真抽样&#xff09;&#xff1a;样值脉冲的幅度随原始信号m(t)的幅度而变&#xff1b; 自然抽样过程的…

个人网站制作 Part 26 添加在线日历功能 | Web开发项目添加页面缓存

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 添加在线日历功能&#x1f528;使用日历服务&#x1f527;步骤 1: 选择日历服务&#x1f527;步骤 2: 安装FullCalendar&#x1f527;步骤 3: 创建FullCalendar组件&…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 生成哈夫曼树(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 生成哈夫曼树(100分) 🌍 评测功能需要订阅专栏后私信联系清…

数据中心布线管理:预标记线缆与移动扫描技术的融合

随着信息技术的飞速发展&#xff0c;数据中心布线管理面临着前所未有的挑战。传统的布线管理方式已无法满足现代数据中心高效、准确和可靠的需求。在这样一个背景下&#xff0c;预标记线缆与移动扫描技术的结合&#xff0c;为数据中心布线管理带来了革命性的解决方案。 布线管理…

基于System-Verilog点亮LED灯

文章目录 一、System-Verilog介绍1.1System-Verilog 二、简单的语法介绍2.1接口实例2.2全局声明和语句实例2.3时间单位和精度2.4用户定义的类型2.5 枚举类型 三、流水灯参考 一、System-Verilog介绍 1.1System-Verilog SystemVerilog是一种硬件描述和验证语言&#xff08;HDV…

stm32f103 HAL库 HC-SR04测距

目录 一、实现测距二、添加TIM3控制LED根据距离以不同频率闪烁三、观察时序Modebus协议12路超声波雷达设计方案1. 系统架构设计2. 硬件设计3. 软件设计4. 通信协议设计5. 用户接口6. 安全和冗余7. 测试和验证8. 电源和物理封装9. 文档和支持 一、实现测距 配置时钟 配置定时器…

八、BGP

目录 一、为何需要BGP&#xff1f; 二、BGP 2.1、BGP邻居 2.2、BGP报文 2.3、BGP路由 2.4、BGP通告遵循原则 2.5、BGP实验 第一步&#xff1a;建立邻居 第二步&#xff1a;引入路由 BGP路由黑洞 路由黑洞解决方案 1、IBGP全互联 2、路由引入 3、MPLS 多协…

【Python】数据处理:Matplotlib绘图

Matplotlib是Python强大的数据可视化工具库&#xff0c;类似于MATLAB语言。Mat-lotlib提供了一整套与MATLAB相似的命令API&#xff0c;十分适合进行交互式制图&#xff0c;而且也可以方便地将它作为绘图控件&#xff0c;嵌入GUI应用程序中。 Matplotlib是神经生物学家John D.Hu…

轻松拿捏C语言——【关机代码】

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 我们可以通过写…

c++编程(16)——STL(4)deque

欢迎来到博主的专栏&#xff1a;c编程 博主ID&#xff1a;代码小豪 文章目录 dequedeque的优劣势deque的操作constructor元素访问 deque deque的全称是double ended queue&#xff0c;译为双端队列&#xff0c;如何理解这个双端呢&#xff1f;我们以vector为例&#xff0c;vec…

深入剖析人才管理的关键要素:“选、用、育、留”四大核心要素

在当今这个日新月异的商业时代&#xff0c;企业的成功不再仅仅取决于资金、技术或市场策略&#xff0c;而更多地依赖于企业所拥有的人才资源。有效的人才管理策略&#xff0c;尤其是“选、用、育、留”四大核心要素&#xff0c;已成为推动企业持续发展的关键。 一、选&#xff…

Canvas绘制老友记时钟

Canvas绘制老友记时钟 前言 一直做3D/2D可视化&#xff0c;Canvas API和三角函数&#xff0c;空间几何是基础。在官网上看了一遍Canvas API之后&#xff0c;决定绘制一个老友记时钟来巩固知识点&#xff0c;本文用实际代码讲解绘制过程。 代码 HTML <canvas id"myC…