介绍:
Linux下通过哪个命令怎么查看中断
与Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq()。
C++是一种面向对象的计算机程序设计语言,由美国ATT贝尔实验室的本贾尼·斯特劳斯特卢普博士在20世纪80年代初期发明并实现,最初它被称作“C with Classes”(包含类的C语言)。
它是一种静态数据类型检查的、支持多重编程范式的通用程序设计语言,支持过程化程序设计、数据抽象、面向对象程序设计、泛型程序设计等多种程序设计风格。
在C基础上,一九八三年又由贝尔实验室的Bjarne Strou-strup推出了C++,C++进一步扩充和完善了C语言,成为一种面向 对象的程序设计语言。
C++目前流行的编译器最新版本是Borland C++ 4.5,Symantec C++ 6.1,和Microsoft Visual C++ 2012。
Linux内核中断之中断调用流程
本文基于 RockPI 4A 单板Linux4.4内核介绍中断调用流程。
ARMv8包括两种运行状态:AArch64和AArch32。
AArch64中不再使用AArch32中的7种特权模式,而是提出了Exception Levels的概念,包括:
1)EL0:用于用户态程序,权限最低
2)EL1:给内核使用,权限稍高
3)EL2:虚拟化相关,权限更高
4)EL3:安全相关,权限最高
Linux内核中一般只使用EL0和EL1。
AArch64异常向量表中的异常包括:
1)Synchronous exception(同步异常)
2)SError
3)IRQ
4)FIQ
注:SError、IRQ和FIQ属于异步异常。
在Linux内核中,在 arch/arm64/kernel/entry.S 文件中定义了异常向量表,内容如下:
选取 el1_irq() 函数介绍Linux内核中断的调用流程。
文件: arch/arm64/kernel/entry.S ,调用流程如下:
1、handle_irq()初始化
在 DTS 解析阶段完成 handle_irq() 函数的初始化,流程如下:
gic_irq_domain_map() 函数中完成了 handle_irq() 函数的赋值,具体执行如下:
2、handle_irq()实现
以共享外设中断 SPI 的中断处理函数 handle_fasteoi_irq() 为例,继续跟踪中断的执行过程。
handle_irq_event_percpu() 函数会调用已经注册的中断处理函数,同时唤醒 irq_thread 线程。
3、中断处理线程
在使用 request_threaded_irq() 函数申请中断时,会创建一个 irq_thread 线程,调用流程如下:
irq_thread 线程平时在睡眠状态,等待 handle_irq_event_percpu() 函数唤醒,进一步执行已注册的中断处理线程函数。
使用 DRM 框架中 HDMI 中断验证中断调用流程。
文件: drivers\gpu\drm\bridge\synopsys\dw-hdmi.c
在中断处理函数 dw_hdmi_hardirq() 和中断处理线程函数 dw_hdmi_irq 中增加 dump_stack() 调用( 注:仅限于调试验证 )。
插入 HDMI 线,系统启动后,显示中断调用流程的日志如下:
和
Linux中断补充
在系统结构中,CPU工作的模式有两种,一种是中断,由各种设备发起;一种是轮询,由CPU主动发起。
中断IRQ:
中断允许让设备(如键盘,串口卡,并口等设备)表明它们需要CPU。一旦CPU接收了中断请求,CPU就会暂时停止执行正在运行的程序,并且调用一个称为中断处理器或中断服务程序(interrupt service routine)的特定程序。CPU处理完中断后,就会恢复执行之前被中断的程序。
中断分类:
硬中断+软中断
硬中断:
①非屏蔽中断:不能被屏蔽,硬件发生的错误:内存错误,风扇故障,温度传感器故障等。
②可屏蔽中断:可被CPU忽略或延迟处理。当缓存控制器的外部针脚被触发的时候就会产生这种类型的中断,而中断屏蔽寄存器就会将这样的中断屏蔽掉。我们可以将一个比特位设置为0,来禁用在此针脚触发的中断。
软中断:
是软件实现的中断,也就是程序运行时其他程序对它的中断;而硬中断是硬件实现的中断,是程序运行时设备对它的中断。
CPU之间的中断处理(IPI)
处理器间中断允许一个CPU向系统其他的CPU发送中断信号,处理器间中断(IPI)不是通过IRQ线传输的,而是作为信号直接放在连接所有CPU本地APIC的总线上。
CALL_FUNCTION_VECTOR (向量0xfb)
发往所有的CPU,但不包括发送者,强制这些CPU运行发送者传递过来的函数,相应的中断处理程序叫做call_function_interrupt(),例如,地址存放在群居变量call_data中来传递的函数,可能强制其他所有的CPU都停止,也可能强制它们设置内存类型范围寄存器的内容。通常,这种中断发往所有的CPU,但通过smp_call_function()执行调用函数的CPU除外。
RESCHEDULE_VECTOR (向量0xfc)
当一个CPU接收这种类型的中断时,相应的处理程序限定自己来应答中断,当从中断返回时,所有的重新调度都自动运行。
INVALIDATE_TLB_VECTOR (向量0xfd)
发往所有的CPU,但不包括发送者,强制它们的转换后援缓冲器TLB变为无效。相应的处理程序刷新处理器的某些TLB表项。
linux系统中的中断指令是什么??
什么是中断
Linux 内核需要对连接到计算机上的所有硬件设备进行管理,毫无疑问这是它的份内事。如果要管理这些设备,首先得和它们互相通信才行,一般有两种方案可实现这种功能:
轮询(polling) 让内核定期对设备的状态进行查询,然后做出相应的处理;中断(interrupt) 让硬件在需要的时候向内核发出信号(变内核主动为硬件主动)。
第一种方案会让内核做不少的无用功,因为轮询总会周期性的重复执行,大量地耗用 CPU 时间,因此效率及其低下,所以一般都是采用第二种方案 。
对于中断的理解我们先看一个生活中常见的例子:QQ。第一种情况:你正在工作,然后你的好友突然给你发送了一个窗口抖动,打断你正在进行的工作。第
二种情况:当然你有时候也会每隔 5 分钟就去检查一下 QQ
看有没有好友找你,虽然这很浪费你的时间。在这里,一次窗口抖动就可以被相当于硬件的中断,而你就相当于 CPU,你的工作就是 CPU
这在执行的进程。而定时查询就被相当于 CPU 的轮询。在这里可以看到:同样作为 CPU 和硬件沟通的方式,中断是硬件主动的方式,较轮询(CPU
主动)更有效些,因为我们都不可能一直无聊到每隔几分钟就去查一遍好友列表。
CPU
有大量的工作需要处理,更不会做这些大量无用功。当然这只是一般情况下。好了,这里又有了一个问题,每个硬件设备都中断,那么如何区分不同硬件呢?不同设
备同时中断如何知道哪个中断是来自硬盘、哪个来自网卡呢?这个很容易,不是每个 QQ 号码都不相同吗?同样的,系统上的每个硬件设备都会被分配一个
IRQ 号,通过这个唯一的 IRQ 号就能区别张三和李四了。
从物理学的角度看,中断是一种电信号,由硬件设备产生,并直接送入中断控制器(如
8259A)的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断。此后,
处理器会通知 OS 已经产生中断。这样,OS
就可以对这个中断进行适当的处理。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识,这些值通常被称为中断请求线。
Linux内核中断之中断申请接口
本文基于 RockPI 4A 单板Linux4.4内核介绍中断申请的常用接口函数。
1、文件
2、定义
说明:
1)、 irq :要申请的中断号,可通过 platform_get_irq() 获取,见“Linux内核中断之获取中断号”。
2)、 handler :中断处理函数,发生中断时,先处理中断处理函数,然后返回 IRQ_WAKE_THREAD 唤醒中断处理线程。中断处理函数尽可能简单。
中断处理函数定义: typedef irqreturn_t (*irq_handler_t)(int, void *);
中断返回值如下:
3)、 thread_fn :中断处理线程,该参数可为NULL。类似于中断处理函数的下半部分。
4)、 irqflags :中断类型标志。
定义文件: include/linux/interrupt.h ,内容如下:
5)、 devname :中断名称,可使用 cat /proc/interrupts 命令查看。
6)、 dev_id :设备ID,该值唯一。
在使用共享中断时(即设置 IRQF_SHARED ),必须传入 dev_id ,在中断处理和释放函数中都会使用该参数。
注:
1、 request_threaded_irq() 函数可替代 request_irq 加 tasklet 或 workqueue 的方式。
2、对应的中断释放函数为: void free_irq(unsigned int, void *) ,需要和中断申请函数成对出现。
1、文件
2、定义
说明:
1)、 __must_check :指调用函数一定要处理函数的返回值,否则编译器会给出警告。
2)、 request_irq() 函数本质上是中断处理线程 thread_fn 为空的 request_threaded_irq() 函数。
注 :
对应的中断释放函数为: void free_irq(unsigned int, void *) ,需要和中断申请函数成对出现。
1、文件
2、定义
说明 :
devm_request_threaded_irq() 本质上还是使用 request_threaded_irq() 函数实现中断申请。
两者区别:
1)多了一个 dev 参数;
2)在设备驱动卸载时,中断会自动释放;
3)如果想单独释放中断,可使用 void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id) 函数。
1、文件
2、定义
devm_request_irq() 函数本质上是中断处理线程 thread_fn 为空的 devm_request_threaded_irq() 函数。
1、获取中断号
2、申请中断
3、中断处理函数
4、中断处理线程
5、查看中断
网友评论
最新评论
应的信号。处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断。此后,处理器会通知 OS 已经产生中断。这样,OS 就可以对这个中断进行适当的处理。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识,这些值通常被称为中断请求线。Lin
,进一步执行已注册的中断处理线程函数。 使用 DRM 框架中 HDMI 中断验证中断调用流程。 文件: drivers\gpu\drm\bridge\synopsys\dw-hdmi.c
函数,同时唤醒 irq_thread 线程。 3、中断处理线程 在使用 request_threaded_irq() 函数申请中断时,会创建一个 irq_thread 线程,调用流程如下: irq_thread 线程平时在睡眠状态,等待 handle_irq_event_percpu
加 dump_stack() 调用( 注:仅限于调试验证 )。 插入 HDMI 线,系统启动后,显示中断调用流程的日志如下: 和Linux中断补充在系统结构中,CPU工作的模式有两种,一种是中断,由各种设备发起;一种是轮询,由CPU主动发起。