我想知道任何微处理器中FIQ和IRQ中断系统之间的区别,例如:ARM926EJ。
Answers:
现代ARM CPU(和其他一些CPU)的功能。
来自专利:
提供了一种在数字数据处理器中执行快速中断的方法,该方法具有处理多个中断的能力。接收到快速中断请求时,将设置一个标志,并将程序计数器和条件代码寄存器存储在堆栈中。在中断服务程序结束时,从中断指令返回将检索条件代码寄存器,其中包含数字数据处理器的状态,并检查是否已设置该标志。如果设置了该标志,则表明已处理了一个快速中断,因此仅取消了程序计数器的堆栈。
换句话说,FIQ只是更高优先级的中断请求,通过在请求服务期间禁用IRQ和其他FIQ处理程序来优先处理FIQ。因此,在处理活动FIQ中断期间不会发生其他中断。
ARM调用FIQ
的快速中断,与寓意IRQ
是正常优先级。在任何实际的系统中,将有不仅两个设备更多的中断源,因此将有一些外部硬件中断控制器允许这些多个源的屏蔽,优先级等,并将中断请求线驱动到处理器。
在某种程度上,这使得两个中断模式之间的区别变得多余,并且许多系统根本不使用nFIQ
或以类似于NMI
其他处理器上的非可屏蔽()中断的方式使用它(尽管FIQ
大多数ARM软件都可屏蔽)处理器)。
那么,ARM为什么将FIQ称为“快速”?
r8-r14
。R14是链接寄存器,用于保存FIQ的返回地址(+4)。但是,如果您的FIQ处理程序能够被编写为仅使用r8-r13
,则可以通过两种方式利用这些存储区寄存器:
r8
可以用作指向硬件设备的指针,并且处理程序可以依赖于r8
下次调用时的相同值。0x1C
)末尾的位置意味着,如果FIQ处理程序代码直接放置在向量表的末尾,则不需要分支-该代码可以直接从执行0x1C
。这样可以节省进入ISR的几个周期。那么为什么许多系统不使用FIQ?
r8-r13
。由符合ARM的ATPCS
过程调用标准的C编译器生成的代码将改用寄存器r0-r3
作为暂存值,并且不会cpsr
在函数末尾生成正确的恢复返回代码。在某些ARM参考中,FIQ或快速中断通常称为软DMA。
的特点FIQ是,
与必须分支的IRQ相比,最后一个功能还具有一点优势。
一些人引用了在汇编器中编码以处理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
以确定缓冲区何时结束。Main(非中断代码)可通过使用指令切换到FIQ模式并将非存储区R0-R7传输到存储区R8-R13寄存器来转移和设置存储区FIQ寄存器。msr
通常,RTOS中断等待时间为500-1000条指令。对于Linux,它可能是2000-10000条指令。始终最好使用实数DMA,但是,对于高频简单中断(如缓冲区传输),FIQ可以提供解决方案。
由于FIQ与速度有关,因此如果您不确定汇编程序中的编码(或愿意花时间),就不应该考虑它。由无限运行的程序员编写的汇编程序比编译器要快。在GCC协助下可以帮助新手。
由于FIQ具有单独的屏蔽位,因此几乎无处不在。在较早的ARM CPU(例如ARM926EJ)上,某些原子操作必须通过屏蔽中断来实现。即使使用最先进的Cortex CPU,在某些情况下OS也会屏蔽中断。通常,服务时间对于中断而言并不重要,但在信号通知和服务之间的时间并不重要。在这里,FIQ也有优势。
该FIQ是不可扩展的。为了使用多个FIQ
源,必须在中断例程之间共享存储区寄存器。另外,必须添加代码以确定是什么原因导致了中断/ FIQ。该FIQ一般是一招的小马。
如果您的中断非常复杂(网络驱动程序,USB等),则FIQ可能毫无意义。这基本上与多路复用中断相同。该编组寄存器产生6-自由变量来使用它永远不会从内存中加载。寄存器比内存快。寄存器比L2缓存快。寄存器比L1缓存快。注册速度很快。如果您不能编写运行6个变量的例程,则FIQ不适合。注意:如果使用16位值,则可以对某些寄存器进行移位和循环加倍,而移位和旋转在ARM上是免费的。
显然,FIQ更复杂。操作系统开发人员希望支持多个中断源。客户对FIQ的要求会有所不同,他们通常会意识到,他们应该让客户自己动手做。通常对FIQ的支持是有限的,因为任何支持都可能会损害主要收益SPEED。
不要抨击我朋友的FIQ。它是系统程序员针对愚蠢的硬件的一个绝招。它不适合每个人,但有它的位置。当其他所有尝试减少延迟和增加ISR服务频率的尝试均告失败时,FIQ可能是您唯一的选择(或更好的硬件团队)。
在某些安全关键型应用程序中,也可以用作紧急中断。
ACK
和EOI
,如果那是您拥有的控制器。
src
必须在寄存器中注册r8
的内容。但是,全局寄存器变量在这里似乎很合适,因为它们确实保留了寄存器。
我相信这是您要寻找的:
http://newsgroups.derkeiler.com/Archive/Comp/comp.sys.arm/2005-09/msg00084.html
本质上,FIQ将具有多个优先级较低的IRQ源,具有最高的优先级。
这取决于我们设计中断处理程序的方式,因为FIQ最后可能不需要一条分支指令,而且它具有唯一的r8-r14寄存器集,因此下一次我们回到FIQ中断时,我们无需压入/弹出堆栈。当然,这样可以节省一些周期,但是要让更多的处理程序为一个FIQ服务也是不明智的,而且FIQ具有更高的优先级,但是没有理由说它可以更快地处理中断,因为两个IRQ / FIQ都以相同的CPU频率运行,因此,它们必须以相同的速度运行。