Linux中断管理

news2024/12/25 23:53:38

Linux 内核提供了完善的中断框架,我们只需要申请中断,然后注册中断处理函数即可,使用非常方便,不需要一系列复杂的寄存器配置。

1.Linux中断简介

中断号

每个中断都有一个中断号,通过中断号即可区分不同的中断,有的资料也把中断号叫做中断线。在 Linux 内核中使用一个 int 变量表示中断号

request_irq函数

在 Linux 内核中要想使用某个中断是需要申请的,request_irq 函数用于申请中断, request_irq函数可能会导致睡眠,因此不能在中断上下文或者其他禁止睡眠的代码段中使用 request_irq 函数。request_irq 函数会激活(使能)中断,所以不需要我们手动去使能中断,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

free_irq函数

使用中断的时候需要通过 request_irq 函数申请,使用完成以后就要通过 free_irq 函数释放掉相应的中断。如果中断不是共享的,那么 free_irq 会删除中断处理函数并且禁止中断
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

中断处理函数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

中断使能/禁止函数

暂时无法在中科创达软件股份有限公司文档外展示此内容
enable_irq 和 disable_irq 用于使能和禁止指定的中断,irq 就是要禁止的中断号。disable_irq函数要等到当前正在执行的中断处理函数执行完才返回,因此使用者需要保证不会产生新的中断,并且确保所有已经开始执行的中断处理程序已经全部退出。在这种情况下,可以使用另外一个中断禁止函数:
暂时无法在中科创达软件股份有限公司文档外展示此内容
disable_irq_nosync 函数调用以后立即返回,不会等待当前中断处理程序执行完毕。
有时候我们需要关闭当前处理器的整个中断系统,也就是在学习 STM32 的时候常说的关闭全局中断:
暂时无法在中科创达软件股份有限公司文档外展示此内容
local_irq_enable 用于使能当前处理器中断系统,local_irq_disable 用于禁止当前处理器中断系统。
暂时无法在中科创达软件股份有限公司文档外展示此内容
这两个函数是一对,local_irq_save 函数用于禁止中断,并且将中断状态保存在 flags 中local_irq_restore 用于恢复中断

2.上半部与下半部

我们在使用request_irq 申请中断的时候注册的中断服务函数属于中断处理的上半部,只要中断触发,那么中断处理函数就会执行。我们都知道中断处理函数一定要快点执行完毕,越短越好,但是现实往往是残酷的,有些中断处理过程就是比较费时间,我们必须要对其进行处理,缩小中断处理函数的执行时间。
上半部:
上半部就是中断处理函数,那些处理过程比较快,不会占用很长时间的处理就可以放在上半部完成。
下半部:
如果中断处理过程比较耗时,那么就将这些比较耗时的代码提出来,交给下半部去执行,这样中断处理函数就会快进快出
Linux 内核将中断分为上半部和下半部的主要目的就是实现中断处理函数的快进快出,那些对时间敏感、执行速度快的操作可以放到中断处理函数中,也就是上半部。剩下的所有工作都可以放到下半部去执行,比如在上半部将数据拷贝到内存中,关于数据的具体处理就可以放到下半部去执行。
Linux 内核提供了多种下半部机制:

软中断

Linux 内核使用结构体 softirq_action 表示软中断, softirq_action结构体定义在文件 include/linux/interrupt.h 中,内容如下:
暂时无法在中科创达软件股份有限公司文档外展示此内容
在 kernel/softirq.c 文件中一共定义了 10 个软中断,如下所示:
暂时无法在中科创达软件股份有限公司文档外展示此内容
NR_SOFTIRQS 是枚举类型,定义在文件 include/linux/interrupt.h 中,定义如下:

softirq_action 结构体中的 action 成员变量就是软中断的服务函数,数组 softirq_vec 是个全局数组,因此所有的 CPU(对于 SMP 系统而言)都可以访问到,每个 CPU 都有自己的触发和控制机制,并且只执行自己所触发的软中断。但是各个 CPU 所执行的软中断服务函数确是相同的,都是数组 softirq_vec 中定义的 action 函数。要使用软中断,必须先使用 open_softirq 函数注册对应的软中断处理函数,open_softirq 函数原型如下:
暂时无法在中科创达软件股份有限公司文档外展示此内容

软中断必须在编译的时候静态注册!Linux 内核使用 softirq_init 函数初始化软中断,softirq_init 函数定义在 kernel/softirq.c 文件里面,函数内容如下:

tasklet

tasklet 是利用软中断来实现的另外一种下半部机制,在软中断和 tasklet 之间,建议大家使用 tasklet。Linux 内核使用 tasklet_struct 结构体来表示 tasklet:

第 489 行的 func 函数就是 tasklet 要执行的处理函数,用户定义函数内容,相当于中断处理
函数。如果要使用 tasklet,必须先定义一个 tasklet,然后使用 tasklet_init 函数初始化 tasklet,
taskled_init 函数原型如下:
暂时无法在中科创达软件股份有限公司文档外展示此内容
t:要初始化的 tasklet
func:tasklet 的处理函数。
data:要传递给 func 函数的参数
也 可 以 使 用 宏 DECLARE_TASKLET 来 一 次 性 完 成 tasklet 的 定 义 和 初 始 化 ,DECLARE_TASKLET 定义在 include/linux/interrupt.h 文件中,定义如下:
暂时无法在中科创达软件股份有限公司文档外展示此内容
其中 name 为要定义的 tasklet 名字,这个名字就是一个 tasklet_struct 类型的时候变量,func就是 tasklet 的处理函数,data 是传递给 func 函数的参数。
在上半部,也就是中断处理函数中调用 tasklet_schedule 函数就能使 tasklet 在合适的时间运
行,tasklet_schedule 函数原型如下:
暂时无法在中科创达软件股份有限公司文档外展示此内容
t:要调度的 tasklet
关于 tasklet 的参考使用示例如下所示:

工作队列

工作队列是另外一种下半部执行方式,工作队列在进程上下文执行,工作队列将要推后的工作交给一个内核线程去执行,因为工作队列工作在进程上下文,所以工作队列允许睡眠或重新调度。如果你要推后的工作可以睡眠那么就可以选择工作队列,否则的话就只能选择软中断或 tasklet。
Linux 内核使用 work_struct 结构体表示一个工作,内容如下(省略掉条件编译):
暂时无法在中科创达软件股份有限公司文档外展示此内容
这些工作组织成工作队列,工作队列使用 workqueue_struct 结构体表示,内容如下

Linux 内核使用工作者线程(worker thread)来处理工作队列中的各个工作,Linux 内核使用worker 结构体表示工作者线程,

从示例代码 51.1.2.10 可以看出,每个 worker 都有一个工作队列,工作者线程处理自己工作队列中的所有工作。在实际的驱动开发中,我们只需要定义工作(work_struct)即可,关于工作队列和工作者线程我们基本不用去管。简单创建工作很简单,直接定义一个 work_struct 结构体变量即可,然后使用 INIT_WORK 宏来初始化工作,INIT_WORK 宏定义如下:
暂时无法在中科创达软件股份有限公司文档外展示此内容
_work 表示要初始化的工作,_func 是工作对应的处理函数。
也可以使用 DECLARE_WORK 宏一次性完成工作的创建和初始化,宏定义如下:
暂时无法在中科创达软件股份有限公司文档外展示此内容
n 表示定义的工作(work_struct),f 表示工作对应的处理函数。
和 tasklet 一样,工作也是需要调度才能运行的,工作的调度函数为 schedule_work,函数原型如下所示:

关于工作队列的参考使用示例如下所示:

3.设备树中断信息节点

如果使用设备树的话就需要在设备树中设置好中断属性信息,Linux 内核通过读取设备树中的中断属性信息来配置中断。对于中断控制器而言,设备树绑定信息参考文档Documentation/devicetree/bindings/arm/gic.txt。

第 2 行,compatible 属性值为“arm,cortex-a7-gic”在 Linux 内核源码中搜索“arm,cortex-a7-gic”即可找到 GIC 中断控制器驱动文件。
第 3 行,#interrupt-cells 和#address-cells、#size-cells 一样。表示此中断控制器下设备的 cells
大小,对于设备而言,会使用 interrupts 属性描述中断信息,#interrupt-cells 描述了 interrupts 属性的 cells 大小,也就是一条信息有几个 cells。每个 cells 都是 32 位整形值,对于 ARM 处理的GIC 来说,一共有 3 个 cells,这三个 cells 的含义如下:
第一个 cells:中断类型,0 表示 SPI 中断,1 表示 PPI 中断。
第二个 cells:中断号,对于 SPI 中断来说中断号的范围为 0~987,对于 PPI 中断来说中断号的范围为 0~15。
第三个 cells:标志,bit[3:0]表示中断触发类型,为 1 的时候表示上升沿触发,为 2 的时候表示下降沿触发,为 4 的时候表示高电平触发,为 8 的时候表示低电平触发。bit[15:8]为 PPI 中断的 CPU 掩码。
第 4 行,interrupt-controller 节点为空,表示当前节点是中断控制器。
简单总结一下与中断有关的设备树属性信息:
暂时无法在中科创达软件股份有限公司文档外展示此内容
获取中断号:

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

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

相关文章

神经网络—卷积层

1.讲解 Conv2d out_channels 参数为2时,会生成两个卷积核,分别与输入进行卷积。得到的两个输出为输出 新生成的卷积核和原来的卷积核不一定相同 in_channels (int) – Number of channels in the input image out_channels (int) – Number of channels…

Marching Cubes 算法再探

Marching Cubes 算法再探 基础过程代码mian.cppMarchingCubes.hMarchingCubes.cpp 之前做NeRF相关工作时简单看过,但没有深究其实现,知其然不知其所以然的程度,算是初探。 基础 为了对MC有大致了解,可以先根据Marching Cubes 算法…

两个实用的Python编程技巧

一、变量类型声明技巧 虽然在Python中可以不用声明变量的类型,但是为了加快程序的运算速度,减少不必要的bug,我们可以在定义变量之初就把它的类型确定,这样可以更好地传输变量值。如下面的例子。 我们定义了两个变量&#xff0c…

IO进程线程 240826作业

作业 创建3个进程,子进程1拷贝文件的前一半,子进程2拷贝后一半文件,父进程回收两个子进程资源。 将1.txt内容拷贝到2.txt中 #include <myhead.h> int main(int argc, const char *argv[]) {pid_t pid1;pid1 fork();int fd1 open("./1.txt",O_RDWR);if(fd1…

JavaWeb JavaScript ④ JS的对象和JSON

只要你的风格是适应客观规律的&#xff0c;那你以后会越来越好&#xff0c;做事情会越来越顺利 —— 24.8.26 一、JS创建对象 语法 方式1 new Object() 方式2 {属性名&#xff1a;属性值&#xff0c;… …&#xff0c;函数名&#xff1a;function(){}} 方式…

Python | Leetcode Python题解之第371题两整数之和

题目&#xff1a; 题解&#xff1a; MASK1 4294967296 # 2^32 MASK2 2147483648 # 2^31 MASK3 2147483647 # 2^31-1class Solution:def getSum(self, a: int, b: int) -> int:a % MASK1b % MASK1while b ! 0:carry ((a & b) << 1) % MASK1a (a ^ b) % MA…

Agent实际落地的应用 未来生活的无形助手

在这个信息爆炸的时代&#xff0c;我们每个人都在追求更高效的生活方式。想象一下&#xff0c;如果有一个无形的助手&#xff0c;能够理解我们的需求&#xff0c;自动处理繁琐的任务&#xff0c;甚至为我们提供个性化的建议&#xff0c;那将是多么美好的体验&#xff01;这正是…

线性DP经典题型

数字三角形&#x1f342; #include<bits/stdc.h> using namespace std; int main() {int n;cin>>n;vector<vector<int>>arr(n1,vector<int>(n1,0));for(int i 1;i<n;i){for(int j 1;j<i;j){cin>>arr[i][j];}}vector<vector<i…

【精选】分享9款AI毕业论文生成初稿题目网站

在当今学术研究领域&#xff0c;AI技术的应用日益广泛&#xff0c;尤其是在学术论文的撰写过程中。AI论文生成器的出现&#xff0c;极大地简化了学术写作流程&#xff0c;提高了写作效率。以下是9款推荐的AI毕业论文生成初稿的网站&#xff0c;它们各有特色&#xff0c;能够满足…

【Qt】多元素控件QTableWidget

多元素控件QTableWidget 使用QTableWidget表示一个表格控件&#xff0c;一个表格中包含若干行、每一个行又包含若干列。 表格中的每一个单元格&#xff0c;都是一个QTableWidget对象。 QTableWidget核心方法 方法说明 item(int row, int column) 根据⾏数列数获取指定的 Q…

【电路笔记】-运算放大器基础

运算放大器基础 文章目录 运算放大器基础1、概述2、运算放大器表示3、开环增益(Open-Loop Gain)4、输入和输出阻抗5、带宽6、偏移电压7、理想运算放大器模型7.1 饱和模式7.2 线性模式8、实际运算放大器9、总结1、概述 本文将介绍运算放大器(也称为运算放大器,Operational …

HandBrakeCLI 压缩工具的简单实用

HandBrakeCLI -i input.mp4 -o output.mp4 --encoder qsv_h264 -b 500k --preset "Android 576p25" --width 320 --height 576 --quiet--encoder qsv_h264 意思代表inter的gpu编码 -b 500k 设置比特率 --preset "Android 576p25" 设置预设 --width 320 --…

揭秘OTP与MTP:你的存储小秘密,一次性和多次可编程大不同!

NVM,即非易失性存储器,是一种非易失性内存。 NVM的特点是存储的数据在断电后不会消失。传统的NVM,如掩模ROM、可编程ROM(PROM)、可擦除可编程ROM(EPROM)、电可擦可编程ROM(EEPROM)、NAND/NOR闪存等,以及目前正在开发的许多新型状态存储器,如磁性存储器(MRAM)、电…

Jar包导入本地maven仓库

当jar包未引入到公共maven仓库时&#xff0c;直接通过maven坐标的方式引入会报错&#xff0c;找不到该依赖。所以可以将jar包导入到本地maven仓库&#xff0c;再通过maven坐标引入后就没有问题。 mvn install:install-file -Dfilexxxxxx.jar -DgroupIdcom.xx -DartifactIdxxxx…

idea debug 各个步骤含义

基本功能 IntelliJ IDEA 的 Debug 功能提供了强大的调试支持&#xff0c;允许开发者逐步执行代码&#xff0c;检查变量值&#xff0c;评估表达式等。以下是 Debug 模式中常见的几个按钮及其含义&#xff1a; Show Execution Point (显示执行点)&#xff1a;将光标跳转到当前正在…

如何使用ssm实现模具制造企业订单跟踪管理系统+vue

TOC ssm256模具制造企业订单跟踪管理系统vue 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;…

编程仙尊——深入理解指针(1)

目录 1.认识指针 2.指针变量和地址 2.1取地址操作符&#xff08;&&#xff09; 2.2 指针变量和解引用操作符 2.3 指针变量的大小 3.指针类型的意义 3.1指针的解引用 3.2 指针-整数 3.3 void*指针 1、认识指针 在生活中&#xff0c;一栋楼的每个房间都会有房间号 …

OpenGL实现3D游戏编程【连载5】——纹理坐标、纹理贴图

OpenGL实现3D游戏编程【连载5】——纹理坐标、纹理贴图 欢迎来到zhooyu的专栏。 个人主页&#xff1a;【zhooyu】 文章专栏&#xff1a;【OpenGL实现3D游戏编程】 本专栏内容&#xff1a; 我们从游戏的角度出发&#xff0c;用C去了解一下游戏中的功能都是怎么实现的。这一切还…

六、前后端分离通用权限系统(6)

&#x1f33b;&#x1f33b; 目录 一、用户管理1.1、代码生成器1.2、用户管理后端 CRUD1.2.1、controller1.2.2、service 接口1.2.3、service 接口实现1.2.4、mapper1.2.5、xml1.2.6、knife4j 测试 1.3、用户管理前端 CRUD1.3.1、添加路由1.3.2、定义基础 api1.3.3、实现页面功…

架构设计(5)服务网格(Service Mesh)

服务网格&#xff08;Service Mesh&#xff09;是一个专门设计的基础设施层&#xff0c;用于管理和处理微服务架构中服务间的通信。服务网格通过在服务间插入代理&#xff0c;提供了一种透明的方式来控制、监控和管理服务之间的流量。以下是关于服务网格的详细介绍&#xff0c;…