| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> linux内核中断(一) -> 正文阅读 |
|
[系统运维]linux内核中断(一) |
一、中断简介中断是指 CPU 在执行程序的过程中,出现了某些突发事件急待处理,CPU 必须暂停当前程序的执行, 转去处理突发事件,处理完毕后又返回原程序被中断的位置继续执行。由于中断的存在极大的提高了 CPU 的运行效率,但是设备的中断会打断内核进程中的正常调度和运行,系统对更高吞吐率的追求势必要求中断服务程序尽量短小精悍。 二、中断上下文为保证系统实时性,中断服务程序必须足够简短,但实际应用中某些时候发生中断时必须处理大量的 事物,这时候如果都在中断服务程序中完成,则会严重降低中断的实时性,基于这个原因,linux 系统提出了一个概念:把中断服务程序分为两部分:中断上下文,也叫做顶半部-底半部 。
三、linux开发使用中断的总体思路linux 中断有专门的中断子系统,其实现原理很复杂,但是驱动开发者不需要知道其实现的具体细节, 只需要知道怎么在设备树中指定中断,如何应用该子系统提供的 API 函数来编写中断相关驱动代码即可。其他的事情,比如设备树中的中断控制器,这些都是由原厂的BSP工程师帮我们写好了,我们不需要来修改他。 四、设备树中配置中断如果一个设备需要用到中断功能,开发人员就需要在设备树中配置好中断属性信息,因为设备树是用来描述硬件信息的,然后Linux内核通过设备树配置的中断属性来配置中断功能。 参考文档: 内核Documentation\devicetree\bindings\interrupt-controller\interrupts.txt 1、各级中断中断控制器在硬件上,“中断控制器”只有GIC这一个,但是我们在软件上也可以把上图中的“GPIO”称为“中断控制器”。 GPIO1连接到GIC,GPIO2连接到GIC,所以GPIO1的父亲是GIC,GPIO2的父亲是GIC。 假设GPIO1有32个中断源,但是它把其中的16个汇聚起来向GIC发出一个中断,把另外16个汇聚起来向GIC发出另一个中断。这就意味着GPIO1会用到GIC的两个中断,会涉及GIC里的2个hwirq。 这些层级关系、中断号(hwirq),都会在设备树中有所体现。 2、中断控制器节点的语法在设备树中,中断控制器节点中必须有的两个属性: interrupt-controller,表明它是“中断控制器”。 #interrupt-cells,表明引用这个中断控制器的话需要多少个cell。 #interrupt-cells的,别的节点要引用这个中断控制器时,需要用几个cells来描述 3、示例
imx6ul.dtsi - arch/arm/boot/dts/imx6ul.dtsi - Linux source code (v5.16.16) - Bootlin
比如,GPI0的节点也可以作为中断控制器,在imx6ul.dtsi文件中GPlO1的节点内容如下图所示:
上述工作都是由原厂的BSP工程师来帮我们写好的,并不需要我们来写。我们需要关注的点是怎么在设备树里面描述一个外设的中断节点,我们来看一个例子: 在这个例子中,我们先使用pinctrl和gpio子系统把这个引脚设置为了gpio功能,因为我们在使用中断的时候需要把引脚设置成输入。然后使用interrupt-parent和interrupts 属性来描述中断。 我们的引脚使用的是gpiol里面的io18,所以我们使用的是gpio1这个中断控制器 interrupts属性设置的是中断源,为什么里面是俩个cells呢,因为我们在gpio1这个中断控制器里面#interrupt-cells的值为2 五、驱动代码中使用中断1、获取中断号当在设备数中使用了interrupt-parent和interrupts 属性来描述中断后,可以通过irq_of_parse_and_map来获取中断号。gpio中断也可以不使用这两个属性,直接通过gpio号来获取中断号。 2、request_irq 函数申请中断request_irq 函数可能会导致睡眠,因此不能在中断上下文或者其他禁止睡眠的代码段中使用。 request_irq 函数会激活(使能)中断,所以不需要我们手动去使能中断
irq
:要申请中断的中断号。 ?
handler
:中断处理函数,当中断发生以后就会执行此中断处理函数。
flags
:中断标志,可以在文件
include/linux/interrupt.h 里面查看所有的中断标志
name
:中断名字,设置以后可以在
/proc/interrupts
文件中看到对应的中断名字。
dev
:如果将
flags
设置为
IRQF_SHARED
的话,
dev
用来区分不同的中断,一般情况下将
dev
设置为 设备结构体,dev
会传递给中断处理函数
irq_handler_t
的第二个参数。
返回值
:
0
中断申请成功,其他负值 中断申请失败,如果返回
-EBUSY
的话表示中断已经被申请了。
3、编写中断处理函数使用 request_irq 函数申请中断的时候需要设置中断处理函数,中断处理函数格式如下所示:
第一个参数是要中断处理函数要相应的中断号。 第二个参数是一个指向 void 的指针,也就是个通用指针,需要与 request_irq 函数的 dev 参数保持一致。用于区分共享中断的不同设备,dev 也可以指向设备数据结构。 中断处理函数的返回值为 irqreturn_t 类型,定义如下所示:
一般中断服务函数返回值使用如下形式: return IRQ_RETVAL(IRQ_HANDLED)
4、释放中断资源中断使用完成以后就要通过 free_irq 函数释放掉相应的中断。如果中断不是共享的,那么 free_irq 会 删除中断处理函数并且禁止中断。free_irq 函数原型如下所示:
irq
:要释放的中断。
dev
:如果中断设置为共享
(IRQF_SHARED)
的话,此参数用来区分具体的中断。共享中断
只有在释放最后中断处理函数的时候才会被禁止掉。
5、中断使能和禁止函数常用的中断使用和禁止函数如下所示:
6、其他
六、综合示例:1、设备树?2、驱动代码3、调试手段
查看中断是否申请注册成功:cat /proc/interrupts命令
其中:48就是中断号 拿到中断号之后,可以看这个中断触发了多少次: ref: 韦东山:在Linux设备树(DTS)中指定中断_在代码中获得中断(附.视频) - 知乎 【北京迅为】嵌入式学习之Linux驱动篇_哔哩哔哩_bilibili https://elixir.bootlin.com/linux/v5.16.16/source/arch/arm/boot/dts/imx6ul.dtsi |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 23:51:00- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |