【ARMv8/v9 异常模型入门及渐进 9 - FIQ 和 IRQ 区别】
文章目录
- 1.1 IRQ 与 FIQ 区别
- 1.1.1 ARMv7 中断向量表
- 1.1.2 FIQ 与 IRQ 差异
- 1.1.3 Linux 禁用 FIQ
- 1.2 ARMv8 FIQ 介绍
上篇文章:ARMv8/v9 异常模型入门及渐进 8 – 安全中断介绍
上篇文章:ARMv8/v9 异常模型入门及渐进 10 – 中断下半部处理方式
1.1 IRQ 与 FIQ 区别
1.1.1 ARMv7 中断向量表
向量表中保存了一系列的跳转指令,当系统发生异常时,由处理器负责将程序执行流转到向量表中的跳转指令,最常见的就是中断向量,应用工程师只需要使用固定的函数名编写中断处理程序,在中断发生时该中断处理程序就会被自动调用,这背后的实现就是中断向量表的功劳。
在 armv7 中,中断向量表可以设置在两个地址:0x00000000 和 0xffff0000,由协处理器 cp15 的 SCTLR 的 bit13 来控制,默认情况下,中断向量表的位置在 0x00000000,实际上,对于操作系统而言,比如 linux,会更倾向于将中断向量表放在 0xffff0000 处,因为 0x0 处在用户空间下,需要额外做一些限制,而 0xffff0000 处在内核空间,另一方面,0 地址通常是 NULL 指针访问的地址,这需要 MMU 做相应的访问限制规则,总之,将向量表放在高地址处会更方便。
armv7 架构中向量表地址内容见下表:

对于ARMv7 linux 的中断向量表的定义在 arch/arm/kernel/entry-armv.S 中:
.L__vectors_start:W(b) vector_rst /* reset mode */W(b) vector_und /* undefined mode */W(ldr) pc, .L__vectors_start + 0x1000 /* svc mode */W(b) vector_pabt /* abort mode (prefetch abort) */W(b) vector_dabt /* abort mode (data abort) */W(b) vector_addrexcptn /* unused */W(b) vector_irq /* irq mode */W(b) vector_fiq /* fiq mode */
当对应的 exception event 发生时,系统会自动地修改 CPSR 状态寄存器,并跳转到上表中的地址执行指令,而软件上要做的,就是在该地址上放置对应的代码,除了 FIQ 之外,其它模式对应的都是一条跳转指令,如果存放多于 4 字节的指令,将会覆盖调用后续的异常向量,因为 FIQ 是最后一条异常向量,根据其特殊性,FIQ 的处理指令可以直接放置在以 0xffff001c 处,当然,具体怎么做由软件的实现来决定。
1.1.2 FIQ 与 IRQ 差异
IRQ 与 FIQ 是 ARM 处理器的两种不同编程模式(ARMv7 Cortex-A 系列 有 7 种处理模式)。
IRQ (Interrupt Request):指中断模式;
FIQ (Fast Interrupt Request):指快速中断模式。
具体差异如下
- 对 FIQ 来说系统必须进快处理中断请求并并快速离开这个模式;
- FIQ 的优先级比 IRQ 高,IRQ 可以被 FIQ 所中断,但 FIQ 不能被 IRQ 所中断;
- FIQ 模式下,比 IRQ 模式多了几个独立的寄存器。ARM 在编译的时候,如果 FIQ 中断处理程序足够用这几个独立的寄存器来运作,它就不会进行通用寄存器的压栈,这样也省了一些时间;
- FIQ 的中断向量地址在
0x0000001C,而 IRQ 的在0x00000018。(也有的在FFFF001C以及FFFF0018)。0x18只能放一条指令,为了不与0x1C处的 FIQ 冲突,这个地方只能跳转,而 FIQ 不一样,0x1C以后没有任何中断向量表了,这样可以直接在0x1C处放 FIQ 的中断处理程序,由于跳转的范围限制,至少少了一条跳转指令; - IRQ 和 FIQ 的响应延迟有区别,IRQ 的响应并不及时, 会延迟几个指令周期才跳转到中断向量处,应该是在等预取的指令执行完。
1.1.3 Linux 禁用 FIQ
FIQ 在 linux 中并没有使用到,如上节内容提到的 FIQ 相对于 IRQ 而言,FIQ 拥有更高的优先级,它可以抢占 IRQ 的执行,同时 FIQ 本身的执行速度比 IRQ 要快一些,这类中断通常用在对响应时间有极高要求的系统中,比如 armv7-R 系列的处理器中会使用到。FIQ 的快速执行一方面体现在它有更高的优先级,另一方面,它拥有单独的寄存器,省去了参数的压栈时间,且处于中断向量表的最后一项,其执行代码不需要经过跳转。
至于为什么 linux 中不使用 FIQ,同时禁止 IRQ 中断的嵌套,这是因为支持中断的嵌套会给系统带来更大的复杂性,同时,过多中断的嵌套很可能导致栈的溢出,另一方面,随着硬件的发展,系统性能的瓶颈并不受限于中断的处理,当然,禁止 FIQ 以及中断的嵌套会略微地降低实时性,但是明显它带来的那点实时性提升并不足以弥补它所带来的缺点,两相权衡之下,在新版的内核中便取消了中断嵌套的支持(老版本中是支持的)。
1.2 ARMv8 FIQ 介绍
TODO
上篇文章:ARMv8/v9 异常模型入门及渐进 8 – 安全中断介绍
上篇文章:ARMv8/v9 异常模型入门及渐进 10 – 中断下半部处理方式
推荐阅读:
https://zhuanlan.zhihu.com/p/362717490
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
