中断状态机
对于 GIC-V2 而言,中断的状态机由 Distributor 维护,每个中断都有一个状态机。
Inactive :中断未激活(未发生)。
Pending:中断到达 GIC ,等待 CPU 的处理。
Active:中断得到 CPU 的应答,中断被CPU处理。
Active and pending :某个中断正在被 CPU 处理,这时候该中断又来了。
来看一个例子:
(a)N 和 M 用来标识两个外设中断,N 的优先级大于 M
(b)两个中断都是 SPI 类型,level trigger,active-high
(c)两个中断被配置为去同一个 CPU
(d)都被配置成 group 0,通过 FIQ 触发中断
Linux 抢占机制
GIC中断控制器支持中断优先级抢占,一个高优先级中断可以抢占一个低优先级且处于active状态的中断,即GIC仲裁单元会记录和比较当前优先级最高的pending状态,然后去抢占当前中断,并且发送这个最高优先级的中断请求给CPU。
从GIC角度看,GIC会发送高优先级中断请求给CPU。但是CPU不一定响应!!!因为在中断处理过程中,CPU处于关中断状态(关闭本CPU),需要等低优先级中断处理完毕,直到发送EOI 给GIC,然后CPU才会响应pending状态中优先级最高的中断进行处理。所以 Linux 下:
1、高优先级中断无法抢占正在执行的低优先级中断。
2、同处于 pending 状态的中断,优先响应高优先级中断进行处理。
3、同优先级同是 pending 状态的中断,选择硬件中断号 ID 最小的一个发给CPU。
这样是可以理解的,如果万一中断大量爆发,中断如果允许嵌套的话,栈会越来越大,会爆掉,所以为了防止这种情况发生,Linux中中断不允许嵌套,单CPU中,在一个中断处理完之前,不会相应另外一个中断,哪怕优先级比它高。
FreeRTOS 中是允许高优先级中断抢占正在执行的低优先级中断,不同系统设定不一样。
中断与进程
进程调度是一个复杂的机制, 根据需求的不同,在不同时刻会切换调度机制,CPU会根据进程优先级、时间片等信息,对不同进程进行调度。
中断可以打断进程的运行,任意一个中断的优先级都比所有的进程高。
在中断处理过程中,主要是 GIC 和 CPU 的交互,即便 GIC 支持高优先级中断抢占正在执行的低优先级中断,发信号给 CPU core,但是CPU core 可以不处理,因为 Linux 中当 CPU core 执行中断处理时,是关中断和关抢占的状态,不再相应中断信号。
也就意味着,在中断优先级这个概念中,只有当 GIC 同时存在多个 pending的中断,这时候会选择优先级最高的去执行,高优先级会抢占低优先级中断(哪怕低优先级先来)。如果低优先级中断处于 active
状态,是不可以被抢占的,这是前后关系。抢占只存在于同时是pending 状态的时候。
全部0条评论
快来发表一下你的评论吧 !