FIQ和IRQ中断系统有什么区别?
我想知道任何微处理器中的FIQ和IRQ中断系统之间的区别,例如:ARM926EJ。
现代ARM CPU(和其他一些)的一个特点。
来自专利:
提供了一种在具有处理多于一个中断能力的数字数据处理器中执行快速中断的方法。 当接收到一个快速中断请求时,一个标志被置位,程序计数器和条件码寄存器被存储在一个堆栈中。 在中断服务程序结束时,来自中断指令的返回检索包含数字数据处理器状态的条件码寄存器,并检查标志是否已被设置。 如果该标志被设置,则表明快速中断被服务,因此只有程序计数器被拆分。
换句话说,FIQ只是一个更高优先级的中断请求,通过在请求服务期间禁用IRQ和其他FIQ处理程序来区分优先级。 因此,在处理有效FIQ中断期间不会发生其他中断。
ARM调用FIQ
快速中断 ,暗示IRQ
是正常的优先级 。 在任何实际系统中,将会有比两个设备更多的中断源,因此会有一些外部硬件中断控制器允许这些多个源的屏蔽,优先级等,并且将中断请求线驱动到处理器。
在某种程度上,这使得两种中断模式之间的区别变得冗余,许多系统完全不使用nFIQ
,或者以类似于在其他处理器上发现的不可屏蔽( NMI
)中断的方式使用它(尽pipeFIQ
是软件可屏蔽的在大多数ARM处理器上)。
那么为什么ARM把FIQ叫做“快”呢?
- FIQ模式有自己的专用存储寄存器
r8-r14
。 R14是保存来自FIQ的返回地址(+4)的链接寄存器。 但是如果你的FIQ处理程序能够被写成只能使用r8-r13
,它可以通过两种方式利用这些分区寄存器:- 其一是它不会造成推送和popup中断服务程序(ISR)使用的任何寄存器的开销。 这样可以节省进入和退出ISR的大量循环。
- 而且,处理程序可以依赖于从一个调用到下一个调用的寄存器中的值,例如,
r8
可以用作指向硬件设备的指针,处理程序可以依靠下一次在r8
的相同值调用。
- exception向量表(
0x1C
)末尾的FIQ位置表示如果FIQ处理程序代码直接放在向量表的末尾,则不需要分支 – 代码可以直接从0x1C
执行。 在进入ISR时节省了几个周期。 - FIQ的优先级高于IRQ。 这意味着当核心发生FIQexception时,它会自动屏蔽掉IRQ。 IRQ不能中断FIQ处理程序。 相反的情况并非如此 – IRQ不会屏蔽FIQ,因此FIQ处理程序(如果使用)可以中断IRQ。 另外,如果IRQ和FIQ请求同时发生,核心将首先处理FIQ。
那么为什么许多系统不使用FIQ?
- FIQ处理程序代码通常不能用C编写 – 它需要直接用汇编语言编写。 如果你非常关心ISR性能,想要使用FIQ,那么在任何情况下,你可能都不希望在C编码时留下几个周期,但更重要的是,C编译器不会产生遵循限制的代码只使用寄存器
r8-r13
。 符合ARM的ATPCS
过程调用标准的C编译器生成的代码将使用寄存器r0-r3
作为暂存值,并且不会在函数结束时产生正确的cpsr
恢复返回码。 - 所有的中断控制器硬件通常都在IRQ引脚上。 只有在连接nFIQinput的单个最高优先级中断源时,使用FIQ才有意义,而许多系统没有一个永久最高优先级的源。 将多个源连接到FIQ,然后在它们之间设置软件优先级没有任何价值,因为这消除了FIQ相对于IRQ的几乎所有优点。
在某些ARM引用中, FIQ或快速中断通常被称为Soft DMA 。
FIQ的特点是,
- 包括堆栈,链接寄存器和R8-R12在内的分区模式。
- 单独的FIQ启用/禁用位。
- 向量表尾(总是在caching中,由MMU映射)。
最后一个特性也比必须支持的IRQ稍微有点优势。
速度演示在'C'
有人引用汇编编写难度来处理FIQ。 gcc
有注释来编写一个FIQ处理程序。 这里是一个例子,
void __attribute__ ((interrupt ("FIQ"))) fiq_handler(void) { /* registers set previously by FIQ setup. */ register volatile char *src asm ("r8"); /* A source buffer to transfer. */ register char *uart asm ("r9"); /* pointer to uart tx register. */ register int size asm ("r10"); /* Size of buffer remaining. */ if(size--) { *uart = *src++; } }
这转化为以下几乎好的汇编程序,
00000000 <fiq_handler>: 0: e35a0000 cmp sl, #0 4: e52d3004 push {r3} ; use r11, r12, etc as scratch. 8: 15d83000 ldrbne r3, [r8] c: 15c93000 strbne r3, [r9] 10: e49d3004 pop {r3} ; same thing. 14: e25ef004 subs pc, lr, #4
在0x1c
的汇编程序例程可能看起来像,
tst r10, #0 ; counter zero? ldrbne r11, [r8] ; get character. subne r10, #1 ; decrement count strbne r11, [r9] ; write to uart subs pc, lr, #4 ; return from FIQ.
一个真正的UART可能已经准备好了,但是用FIQ做高速软DMA的代码只有10-20条指令。 主代码需要轮询FIQ r10
以确定缓冲区何时完成。 主(非中断代码)可以通过使用msr
指令切换到FIQ模式来传送和设置存储的FIQ寄存器,并将非存储的R0-R7传送到存储的R8-R13寄存器。
通常RTOS中断延迟将是500-1000条指令。 对于Linux,它可能是2000-10000条指令。 真正的DMA总是比较好,但是,对于高频简单中断(如缓冲区传输), FIQ可以提供解决scheme。
由于FIQ是关于速度的,所以如果在编译器中编码不安全(或者愿意花时间),就不应该考虑这个问题。 由无限运行的程序员编写的汇编程序将比编译程序更快。 有GCC协助可以帮助新手。
潜伏
由于FIQ拥有独立的屏蔽位,因此几乎无处不在。 在较早的ARM CPU(如ARM926EJ)上,一些primefaces操作必须通过屏蔽中断来实现。 即使使用最先进的Cortex CPU,在某些情况下,操作系统也会屏蔽中断。 服务时间通常不是中断的关键,而是信令和服务之间的时间。 在这里, FIQ也有优势。
弱点
FIQ不可扩展。 为了使用多个FIQ
源,分组寄存器必须在中断例程之间共享。 此外,必须添加代码以确定是什么导致了中断/ FIQ。 FIQ通常是一个小把戏 。
如果你的中断非常复杂(networking驱动,USB等),那么FIQ可能没什么意义。 这与复用中断基本相同。 分区寄存器提供6个自由variables来使用永远不会从内存中加载的variables。 寄存器比内存更快。 寄存器比L2caching更快。 寄存器比L1caching更快。 注册速度很快。 如果你不能写一个运行6个variables的例程,那么FIQ是不合适的。 注意:如果使用16位值,则可以使用ARM上的空闲和旋转双重任务寄存器。
FIQ显然更为复杂。 OS开发人员希望支持多个中断源。 客户对FIQ的要求会有所不同,他们往往意识到应该让客户自己来推销 。 通常对FIQ的支持是有限的,因为任何支持都可能削弱SPEED的主要收益。
概要
不要打我的朋友FIQ 。 这是一个系统程序员对付愚蠢的硬件的一招。 这不适合每个人,但它有它的位置。 当所有其他尝试减less延迟并提高ISR服务频率失败时, FIQ可能是您唯一的select(或更好的硬件团队)。
在一些安全关键的应用中,也可以用作恐慌中断。
混沌已经得到了很好的回应,但是到目前为止还没有涉及的一个附加点是FIQ在向量表的末尾,所以在这里开始这个例程是常见的/传统的,而IRQ向量通常就是这样。 (即跳转到其他地方)。 完全存储和上下文切换后立即避免多余的分支是一个轻微的速度增益。
FIQ优先级较高,可以在处理另一个IRQ时引入。 最关键的资源由FIQ处理,其余的由IRQ处理。
另一个原因是在FIQ的情况下,需要较less数量的寄存器来压栈,FIQ模式有R8到R14_fiq寄存器
我相信这是你正在寻找的东西:
http://newsgroups.derkeiler.com/Archive/Comp/comp.sys.arm/2005-09/msg00084.html
本质上,FIQ将具有多个低优先级IRQ源的最高优先级。
没有关于FIQ的任何魔术。 FIQ只是可以中断任何其他正在服务的IRQ,这就是为什么它被称为“快”。 系统对这些中断反应更快,但其余部分是相同的。
FIQs是更高的优先级,毫无疑问,剩下的点我不确定….. FIQs将支持高速数据传输(或)通道处理,需要高速数据处理我们使用FIQs和一般IRQs使用正常中断处理。
这取决于我们如何devise中断处理程序,因为FIQ终于可能不需要一个分支指令,它也有一套独特的r8-r14寄存器,所以下次我们回到FIQ中断时,我们不需要按下/popup叠加。 当然,它可以节省一些周期,但是同样有更多的处理器服务于一个FIQ是不明智的,并且是FIQ具有更多的优先级,但是没有任何理由说它更快地处理中断,IRQ / FIQ在相同CPU频率下运行,所以他们必须以相同的速度运行。
这可能是错的。 我所知道的是,FIQ代表快速中断请求,IRQ代表中断请求。 从这些名字来看,我猜测FIQ的处理(抛出?)比IRQ快。 这可能与处理器的devise有关,FIQ将比IRQ更快地中断处理。 我道歉,如果我错了,但我通常做更高层次的编程,我只是猜测现在。