[IMX6ULL驱动开发]-Linux对中断的处理(二)

news/2024/7/25 11:18:56/文章来源:https://blog.csdn.net/m0_72372635/article/details/139247723

上一篇文章中,引入了Linux对于中断的一些简略流程以及中断抽象为具体实际形象。此文章主要是继续加深对Linux对中断的处理流程以及一些相应的数据结构。

目录

Linux对中断的扩展:硬件中断、软件中断

多中断处理

中断上下部处理流程

发生中断A,并被中断A打断

发生中断A,并被中断B打断

下半部处理时间过长

Linux中断系统重要的数据结构

irq_desc

irqaction结构体

irq_data结构体

irq_domain 结构体

irq_chip 结构体


Linux对中断的扩展:硬件中断、软件中断

对于像按键等硬件所产生的中断称之为硬件中断,Linux中每一个硬件中断都有一个对应的中断号以及处理函数。可以这么简单的理解,有一个硬件中断函数数组,数组中第几个数据对应第几个中断号,以及对应的中断处理函数。

相应的,也有软件中断,相比于硬件中断,软件中断多了一个flag标志位,用来表示中断是否发生了 。

对于软件中断,只要flag标志位被置为1,那么就表示发生了该软件中断。同时,相比于硬件中断,软件中断的优先级会更低,优先处理的是硬件中断。如下是软件中断的枚举。

那么如何触发软件中断呢,最核心的函数是raise_softirq,它的形参是软件中断号,当设置后,系统会设置改软件中断为待处理状态,等到硬件中断处理完成后,会处理这个软件中断。

void raise_softirq(unsigned int nr);

那如何注册软件中断的处理函数呢,系统使用open_softirq函数,这个函数可以给对应的软件中断注册处理函数。

void open_softirq(int nr, void (*action) (struct soft_action*));

多中断处理

如果一个中断需要消耗过多的时间来处理,那么我们可以把中断分为中断上部和中断下部,中断上部用来处理紧急的中断,下部用来处理非紧急的中断。当我们在中断上部处理紧急的中断的时候,是关闭中断的,当处理完紧急的中断,来到中断下部,此时重新打开中断,处理比较不紧急的中断。

中断上下部处理流程

发生中断A,并被中断A打断

假如发生中断A,中断上半部优先级高首先执行,count首先++,执行完中断后--,此时count为0,进入中断下半部,此时count++,开启中断,此时再次发生中断A打断中断下半部,继续走到步骤1这里,count++,执行中断,count--,此时count等于1,并不会进入中断下半部,而是直接完成处理,此时恢复现场,到步骤7,执行完中断A的下半部,count--,此时count为0。完成完整的中断流程。可见,不管多少个中断,中断上半部和中断下半部是N对1的关系,也就是中断下半部只会执行一次

发生中断A,并被中断B打断

假如发生中断A,中断上半部优先级高首先执行,count首先++,执行完中断后--,此时count为0,进入中断下半部,此时count++,开启中断,此时,B中断打断了A中断的中断下半部,回到步骤1,此时执行的是中断B的中断上半部,count++,执行中断B,count--,此时count等于1,并不会进入中断下半部,而是直接完成处理,此时恢复现场,到步骤7,执行完中断A以及中断B的下半部,count--,此时count为0。完成完整的中断流程。可见,中断下半部的处理是多个中断下半部一起进行处理的,而不是单独处理


下半部处理时间过长

一般来说,中断下半部是用来处理那些比较不重要的软件中断,那么假如中断下半部处理的中断也需要占用非常久的时间怎么办呢。

毕竟还是在中断中,其他进程线程是无法执行的,假如存在GUI的进程,会导致页面卡死。所以,假如中断所需要的时间实在是太耗时了,我们就不使用软件中断来处理,而是使用内核线程来处理,此时中断下半部就是内核线程,和进程一样都有竞争执行的机会

如下为一些系统的内核线程

kworker线程是内核线程的一种,它要去工作队列(work queue)上取出一个个工作(work)来执行,那么我们该怎么把一个个work放在work queue上面呢。

、创建work,先写一个处理函数,在调用函数把这个处理函数填充进work结构体中。

、结构体创建完成了,我们需要把该结构体提交给work queue,一般在中断上半部,调用schedule_work 函数把work交给work queue

、放进后,只需要等线程抢占运行即可,这样中断下半部就可以和其他进程抢占CPU执行,这样就不存在因为中断时间过久导致其他进程过久无法相应

总的来说,对于那些很耗时的中断,我们可以交给内核线程来进行处理,内核线程我们可以看成线程,不当成中断来看待,那对应可以抢占运行,也会休眠


Linux中断系统重要的数据结构

irq_desc

irq_desc结构体的主要内容如下:

每一个 irq_desc 数组项中都有一个函数:handle_irq,还有一个 action 链表。handle_irq为中断处理函数,action链表主要存放各个中断控制器上下级中断的中断处理函数。

外部中断1、中断n共享了B号中断,多个GPIO控制器的中断汇集到GIC的A号中断。当发生了中断,是从左到右依次中断,最后中断掉CPU。

CPU处理的时候,则是从右到左依次进行处理,CPU会首先读取GIC,获取中断号A,调用中断A的handle_irq(irq_desc[A].handle_irq 中断处理函数,BSP工程师提供),获取到发生中断的中断号B,此时调用irq_desc[B]. handle_irq,中断B为共享中断,irq_desc[B]存在一个action链表,里面记录了各个共享中断的外部设备中断函数,一旦确定了中断来自中断B,此时会一一执行中断B中(irq_desc[B])的action链表,把各个B号中断下的外接设备的中断函数一一执行,以此确定到底是哪个外部设备发生了中断。

irqaction结构体

irqaction 结构体存在于irq_desc结构体下,主要的内容如下:

当调用 request_irq、request_threaded_irq 注册中断处理函数时,内核就会构造一个 irqaction 结构体。在里面保存 name、dev_id 等,最重要的 是 handler、thread_fn、thread。

handler 是中断处理的上半部函数,用来处理紧急的事情。 thread_fn 对应一个内核线程 thread,当 handler 执行完毕,Linux内核会唤醒对应的内核线程。在内核线程里,会调用 thread_fn 函数。

irq_data结构体

它就是个中转站,里面有 irq_chip 指针 irq_domain 指针,都是指向别的 结构体。

还有两个成员: irq、hwirq,irq 是软件中断号,hwirq 是硬件中断号。 比如上面我们举的例子,在 GPIO 中断 B 是软件中断号,可以找到 irq_desc[B] 这个数组项;GPIO 里的第 x 号中断,这就是 hwirq。比如说GPIO3的5号引脚中断和GPIO4的5号引脚中断,两个的软件中断号是不同的。

irq_domain结构体中的函数会把hwirq映射为软件中断号irq。

irq_domain 结构体

interrupt-parent = <&gpio1>;

interrupts = <5 IRO_TYPE_EDGE_RISING>;

如上表示 GPIO1的5号引脚,通过上升沿触发中断。此时,hwirq就是5,但是它属于的domain属于GPIO1。

irq_domain 结构体中的如下两个函数用来解析设备树中得到的中断数据:

 xlate :用来解析设备树的中断属性,提取出 hwirq、type 等信息。比如上面举例的,hwirq就是5,type 就是IRO_TYPE_EDGE_RISING

 map :把 hwirq 转换为 irq。

irq_chip 结构体

irq_chip 结构体的主要成员如下:

在 request_irq 创建中断后,并不需要手工去使能中断,原因就是系统调用对 应的 irq_chip 里的函数帮我们使能了中断。

我们提供的中断处理函数中,也不需要执行主芯片相关的清中断操作,也是 系统帮我们调用 irq_chip 中的相关函数。 但是对于外部设备相关的清中断操作,还是需要我们自己做的。

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

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

相关文章

Golang | Leetcode Golang题解之第104题二叉树的最大深度

题目&#xff1a; 题解&#xff1a; func maxDepth(root *TreeNode) int {if root nil {return 0}queue : []*TreeNode{}queue append(queue, root)ans : 0for len(queue) > 0 {sz : len(queue)for sz > 0 {node : queue[0]queue queue[1:]if node.Left ! nil {queue…

第十四届蓝桥杯c++研究生组

A 关键思路是求每个十进制数的数字以及怎么在一个数组中让判断所有的数字次数相等。 求每个十进制的数字 while(n!0){int x n%10;//x获取了n的每一个位数字n/10;}扩展&#xff1a;求二进制的每位数字 &#xff08;注意&#xff1a;进制转换、1的个数、位运算&#xff09; x…

骨折分类数据集1129张10类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;1129 分类类别数&#xff1a;10 类别名称:["avulsion_fracture",…

景源畅信:抖音小店新手小白如何做好运营?

在数字时代的浪潮中&#xff0c;抖音小店成为了众多创业者和商家的新宠。但面对激烈的市场竞争和不断变化的平台规则&#xff0c;新手小白如何才能在抖音小店的海洋里稳健航行&#xff0c;捕捉到属于自己的商机呢?接下来的内容将为你揭晓答案。 一、精准定位&#xff0c;明确目…

常见开源蜜罐系统

蜜罐系统&#xff08;Honeypot&#xff09;在信息安全领域中是一种被广泛使用的技术&#xff0c;旨在吸引和诱导黑客入侵&#xff0c;从而获取和分析攻击者的行为和手段。以下是一些常见的蜜罐系统的介绍&#xff1a; HFish开源蜜罐系统 特点&#xff1a; 多功能&#xff1a;支…

Windows hook介绍与代码演示

Windows Hook 是一种机制&#xff0c;允许应用程序监视系统或处理特定事件。它可以拦截和更改消息&#xff0c;甚至可以插入到其他应用程序的消息处理机制中。Windows 提供了多种挂钩类型&#xff0c;例如键盘挂钩、鼠标挂钩、消息挂钩等。 hook代码实现 下面是一个使用 Wind…

就说说Java初学者求职准备项目的正确方式

当下不少Java初学者也知道求职时项目的重要程度&#xff0c;但在简历上写项目和准备面试项目时&#xff0c;真有可能走弯路&#xff0c;这样的话&#xff0c;加重学习负担还是小事&#xff0c;还真有可能导致无法入职。 1 对于在校生和应届生来说&#xff0c;你去跑通个学习项…

pillow学习3

Pillow库中&#xff0c;图像的模式代表了图像的颜色空间。以下是一些常见的图像模式及其含义&#xff1a; L&#xff08;灰度图&#xff09;&#xff1a;L模式表示图像是灰度图像&#xff0c;每个像素用8位表示&#xff08;范围为0-255&#xff09;&#xff0c;0表示黑色&#…

idea的project structure下project [lauguage ]()level 没有java的sdk17选项如何导入

idea的project structure下project lauguage level 没有java的sdk17选项如何导入 别导入了&#xff0c;需要升级idea版本。idea中没有project language level没有17如何添加 - CSDN文库 别听这文章瞎扯淡 2021版本就是没有&#xff0c;直接卸载升级到最新版本就可以了。没办法…

qmt量化交易策略小白学习笔记第8期【qmt编程之获取股票资金流向数据--内置Python】

qmt编程之获取股票资金流向数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 感谢关注&#xff0c;需免费开通量化回测与咨询实盘权限&#xff0c;可以和博主联系&#xff01; 获取股票资金…

云服务器平台AutoDL--基本介绍与使用感受

因为课程作业需要复现DreamBooth&#xff0c;找了几个教程之后&#xff0c;发现了AutoDL这个好东西&#xff0c;芜湖~ 相关概念 以下回答来自于ChatGPT。 云计算平台&#xff1a;云服务器平台是提供按需计算资源和服务的在线平台&#xff0c;通常包括存储、处理能力、数据库、…

微服务架构下的‘黑带’安全大师:Spring Cloud Security全攻略!

深入探讨了微服务间的安全通信、安全策略设计以及面对经典安全问题的应对策略。无论你是微服务的新手还是资深开发者&#xff0c;都能在本文中找到提升安全功力的秘籍。让我们一起成为微服务架构下的‘黑带’安全大师&#xff01; 文章目录 1. 引言微服务安全挑战与重要性Sprin…

链表mark

什么是链表&#xff0c;链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是指针域&#xff08;存放指向下一个节点的指针&#xff09;&#xff0c;最后一个节点的指针域指向null&#xff08;空指针的意思&#xff09;。…

JRebel 激活及使用

插件下载 JRebel and XRebel - IntelliJ IDEs Plugin | Marketplace 从磁盘安装下载的插件 windows下载激活服务 Releases ilanyu/ReverseProxy GitHub mac没有对应版本&#xff0c;需要Docker搭建本地激活服务 docker pull qierkang/golang-reverseproxy docker run -d -…

Steamdeck使用Windows系统游玩雪地奔驰时闪退问题解决方法

我非常喜欢雪地奔驰这款游戏&#xff0c;买sd的一部分也是为了它。可在我打开这个游戏时&#xff0c;游戏发生闪退问题。查阅了网络各个途径&#xff0c;基本没有解决方法。因此我自己分析终于解决该问题。以下是我解决问题的思路&#xff0c;仅供记录参考&#xff1a; 游戏在崩…

第97天:权限提升-Web 权限权限划分源码后台中间件第三方数据库等

前置知识 具体有哪些权限需要我们了解掌握的 后台权限&#xff0c;网站权限&#xff0c;数据库权限&#xff0c;接口权限&#xff0c;系统权限&#xff0c;域控权限等 以上常见权限获取方法简要归类说明 后台权限&#xff1a;SQL 注入,数据库备份泄露&#xff0c;默认或弱口…

[LLM-Agent]万字长文深度解析规划框架:HuggingGPT

HuggingGPT是一个结合了ChatGPT和Hugging Face平台上的各种专家模型&#xff0c;以解决复杂的AI任务&#xff0c;可以认为他是一种结合任务规划和工具调用两种Agent工作流的框架。它的工作流程主要分为以下几个步骤&#xff1a; 任务规划&#xff1a;使用ChatGPT分析用户的请求…

Vue:快速上手

一、简介 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;…

selenium 学习笔记(一)

pip的安装 新建一个txt curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py 把上面的代码复制进去后&#xff0c;把后缀名改为.bat然后双击运行 当前目录会出现一个这个文件 然后在命令行pyhon get-pip.py等它下好就可以了selenium安装 需要安装到工程目…

Halcon 极坐标转换图像

一、概述 先看效果 将圆形的用极坐标转换成矩性然后再进行识别或者其他缺陷检测&#xff0c;最后在还圆到原图中 二、原理&#xff1a; halcon 圆环类缺陷检测的一种方法&#xff08;极坐标变换法&#xff09;_halcon缺口检测-CSDN博客 图像极坐标变换与反变换&#xff08;…