中断

中断向量

arm-linux中,中断号是gic区分不同中断的标志,中断向量是cpu区分不同中断类的标志

 

 

 

 

 

IRQ

硬件中断:由外设产生,将下一条要执行的指令的地址压入栈作为中断服务程序的返回地址

向量中断:直接跳转到预先提供的中断服务程序(比如stm32就时给每个中断提供了向量),多核的话由分配器给各个cpu分配中断,中断也可以负载均衡

非向量中断:先跳到中断解析程序(入口是0x18),引导系统进入fiq/irq模式;通过中断状态寄存器找到中断源再跳到对应的执行程序

SWI

比如系统调用int80,调试指令int3都会触发软中断,并根据中断号去做对应处理,如下图,通过指令SWI,其低24位保存软中断号

 

触发软件中断,进入管理模式,CPU将强制将PC的值置为异常向量表地址0x08;在异常向量表0x08处安放跳转指令b HandleSWI,这样CPU就跳往我们自己定义的HandleSWI处执行;有的机器中断向量存储的直接是中断服务程序的入口地址

异常:CPU无法完成一些指令产生异常,比如除以0,缺页异常,异常发生时将当前指令压入栈,作为中断服务程序的返回地址

陷入:CPU在执行程序过程中,由专设的指令产生陷入,比如int80产生系统调用,发生陷入时,将下一条指令作为中断服务程序的返回地址;还有中止

 

Softirq

每个cpuirq_cpustat_t中有__softirq_pending,是32位的位图,如果第n位为1,则代表对应类型的软中断待处理,通过local_softirq_pending()宏获取,下图有四种触发软中断的方式,或者说是软中断执行时机

 

中断嵌套/屏蔽

硬件平台一般都有硬件优先级,像实时操作系统还可以通过优先级去嵌套,来达到硬实时,但Linux系统为了简化设计,后续就没有中断优先级的概念了,因为想要中断服务快速完成,处理时直接关闭了中断;中断请求信号由完成触发器D的输出与屏蔽触发器MASK输入共同决定是否能产生中断信号;其实也可以优先级嵌套:只要屏蔽字比该中断优先级低的中断对应位设置为1。进入不同中断切换屏蔽字就能实现嵌套了。

 

CPU一般设置两根中断请求输入线:可屏蔽中断请求INTR(Interrupt Require)和不可屏蔽中断请求NMI(NonMaskable Interrupt)。对于可屏蔽中断,除了受本身的屏蔽位控制外,还都要受一个总的控制,即CPU标志寄存器中的中断允许标志位IF(Iinterrupt Flag)的控制,IF位为1,可以得到CPU的响应,否则,得不到响应;EFLAGS中的IF标志不能屏蔽使用INT指令从软件中产生的中断”,“IF标志并不影响发送到NMI引脚的非屏蔽中断,也不影响处理器产生的异常

中断下半部

软中断:有优先级,但不能抢占,因为是串行执行的,会从链表中选取优先级最高的执行

Tasklet:有优先级,本质也是软中断,它有两个工作链表,分别代表高低优先级

Workqueue:有多个工作队列,工作在不同优先级,不同与tasklet,它队列内的优先级也不同,而且执行的回调函数实体是线程,可通过nice值配置优先级

综上:软中断使用麻烦,tasklet经常会拖慢实时响应,建议用工作队列

 

posted on 2022-03-08 22:00  lzd626  阅读(264)  评论(0编辑  收藏  举报