78

我想知道任何微处理器中FIQ和IRQ中断系统的区别,例如:ARM926EJ。

4

11 回答 11

167

ARM 调用快速中断,其含义FIQ是正常优先级。在任何实际系统中,都会有更多的中断源而不仅仅是两个设备,因此会有一些外部硬件中断控制器允许对这些多个源进行屏蔽、优先级排序等,并将中断请求线驱动到处理器。IRQ

在某种程度上,这使得两种中断模式之间的区别变得多余,许多系统根本不使用nFIQ它,或者以类似于NMI在其他处理器上发现的不可屏蔽 ( ) 中断的方式使用它(尽管FIQ在大多数 ARM 上是软件可屏蔽的处理器)。

那么为什么 ARM 将 FIQ 称为“快”呢?

  1. FIQ 模式有自己的专用存储寄存器,r8-r14. R14 是链接寄存器,它保存来自 FIQ 的返回地址 (+4)。但是,如果您的 FIQ 处理程序能够编写为仅使用r8-r13,它可以通过两种方式利用这些存储的寄存器:
    • 一是它不会产生推送和弹出中断服务程序 (ISR) 使用的任何寄存器的开销。这可以节省大量进入和退出 ISR 的周期。
    • 此外,处理程序可以依赖于从一次调用到下一次调用时保留在寄存器中的值,因此例如r8可以用作指向硬件设备的指针,并且处理程序可以依赖于r8下一次调用时存在的相同值。
  2. 异常向量表末尾的 FIQ 位置 ( 0x1C) 意味着如果 FIQ 处理程序代码直接放在向量表的末尾,则不需要分支 - 代码可以直接从0x1C. 这节省了进入 ISR 的几个周期。
  3. FIQ 的优先级高于 IRQ。这意味着当内核接受 FIQ 异常时,它会自动屏蔽 IRQ。IRQ 不能中断 FIQ 处理程序。反之则不然——IRQ 不屏蔽 FIQ,因此 FIQ 处理程序(如果使用)可以中断 IRQ。此外,如果 IRQ 和 FIQ 请求同时发生,核心将首先处理 FIQ。

那么为什么很多系统不使用 FIQ 呢?

  1. FIQ 处理程序代码通常不能用 C 编写 - 它需要直接用汇编语言编写。如果您足够关心 ISR 性能而想要使用 FIQ,那么无论如何您可能都不想通过用 C 进行编码而在桌面上留下几个周期,但更重要的是,C 编译器不会生成遵循以下限制的代码仅使用寄存器r8-r13。由符合 ARMATPCS过程调用标准的 C 编译器生成的代码将改为使用寄存器r0-r3来存储临时值,并且不会cpsr在函数结束时生成正确的恢复返回代码。
  2. 所有中断控制器硬件通常都在 IRQ 引脚上。仅当您有一个连接到 nFIQ 输入的最高优先级中断源并且许多系统没有一个永久最高优先级源时,使用 FIQ 才有意义。将多个源连接到 FIQ,然后在它们之间设置软件优先级是没有价值的,因为这几乎消除了 FIQ 相对于 IRQ 的所有优势。
于 2013-01-08T09:50:09.853 回答
75

在某些 ARM 参考资料中,FIQ快速中断通常称为软 DMA 。FIQ
的特点是,

  1. 具有分组寄存器的分离模式,包括堆栈、链接寄存器和 R8-R12。
  2. 单独的 FIQ 启用/禁用位。
  3. 向量表的尾部(始终在缓存中并由 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 条指令。主代码需要轮询 FIQr10以确定缓冲区何时完成。Main(非中断代码)可以通过使用指令切换到FIQ模式并将 non-banked R0-R7 传输到 banked R8-R13 寄存器来传输和设置 banked FIQ寄存器。msr

通常 RTOS 中断延迟为 500-1000 条指令。对于 Linux,它可能有 2000-10000 条指令。真正的 DMA 总是更可取,但是,对于高频简单中断(如缓冲区传输),FIQ可以提供解决方案。

由于FIQ是关于速度的,如果您在汇编程序中编码不安全(或愿意花时间),则不应考虑它。由无限运行的程序员编写的汇编程序将比编译器更快。有 GCC 协助可以帮助新手。

潜伏

由于FIQ有一个单独的掩码位,它几乎无处不在。在早期的 ARM CPU(例如 ARM926EJ)上,一些原子操作必须通过屏蔽中断来实现。即使使用最先进的 Cortex CPU,在某些情况下操作系统也会屏蔽中断。通常,服务时间对于中断来说并不重要,而是信号和服务之间的时间。在这里,FIQ也有优势。

弱点

FIQ不可扩展。为了使用多个FIQ源,分组寄存器必须在中断例程之间共享。此外,必须添加代码以确定导致中断/FIQ 的原因。FIQ通常是一招一式的小马

如果您的中断非常复杂(网络驱动程序、USB 等),那么 FIQ 可能没什么意义。这与多路复用中断基本相同。分组寄存器提供了 6 个自由变量以供使用,这些变量永远不会从内存中加载。寄存器比内存快。寄存器比二级缓存快。寄存器比 L1-cache 快。寄存器很快。如果您不能编写一个运行 6 个变量的例程,则FIQ不适合。注意:如果您使用 16 位值,您可以使用 ARM 上免费的移位循环对某些寄存器进行双重工作。

显然FIQ更复杂。OS 开发人员希望支持多个中断源。客户对FIQ的要求会有所不同,他们经常意识到他们应该让客户自己动手。通常对FIQ的支持是有限的,因为任何支持都可能减损主要好处SPEED

概括

不要抨击我的朋友FIQ。这是系统程序员对付愚蠢硬件的一招。它并不适合所有人,但它有它的位置。当所有其他减少延迟和增加 ISR 服务频率的尝试都失败时,FIQ可能是您唯一的选择(或更好的硬件团队)。

它还可以在某些安全关键应用程序中用作紧急中断。

于 2014-01-21T22:17:46.410 回答
64

现代 ARM CPU(和其他一些)的一个特性。

来自专利:

提供了一种在具有处理多于一个中断的能力的数字数据处理器中执行快速中断的方法。当接收到快速中断请求时,会设置一个标志,并将程序计数器和条件代码寄存器存储在堆栈中。在中断服务程序结束时,中断指令的返回检索包含数字数据处理器状态的条件代码寄存器,并检查标志是否已设置。如果设置了该标志,则表示处理了一个快速中断,因此只有程序计数器被取消堆栈。

换句话说,FIQ 只是一个更高优先级的中断请求,通过在请求服务期间禁用 IRQ 和其他 FIQ 处理程序来确定优先级。因此,在处理活动 FIQ 中断的过程中不会发生其他中断。

于 2009-06-19T04:58:03.810 回答
6

Chaos 已经很好地回答了,但到目前为止还没有提到的一点是 FIQ 位于向量表的末尾,因此通常/传统的只是从那里开始例程,而 IRQ 向量通常就是这样。(即跳转到其他地方)。在完全存储和上下文切换后立即避免额外的分支是一个轻微的速度增益。

于 2009-06-24T14:38:05.613 回答
5

另一个原因是在 FIQ 的情况下,需要较少数量的寄存器来推入堆栈,FIQ 模式有 R8 到 R14_fiq 寄存器

于 2010-06-23T16:46:22.813 回答
3

FIQ 具有更高的优先级,可以在处理另一个 IRQ 时引入。最关键的资源由 FIQ 处理,其余由 IRQ 处理。

于 2009-06-19T04:56:49.663 回答
1

我相信这就是您正在寻找的:

http://newsgroups.derkeiler.com/Archive/Comp/comp.sys.arm/2005-09/msg00084.html

从本质上讲,FIQ 将具有多个优先级较低的 IRQ 源的最高优先级。

于 2009-06-23T14:39:02.577 回答
1

毫无疑问,FIQ 具有更高的优先级,其余点我不确定...... FIQ 将支持高速数据传输(或)通道处理,在需要高速数据处理的情况下,我们使用 FIQ,通常使用 IRQ 进行正常中断处理.

于 2010-11-16T11:53:37.283 回答
0

FIQ 没有任何魔力。FIQ 只是可以中断正在服务的任何其他 IRQ,这就是它被称为“快速”的原因。系统对这些中断的反应更快,但其余部分相同。

于 2011-07-05T14:23:34.907 回答
0

这取决于我们如何设计中断处理程序,因为 FIQ 最终可能不需要一个分支指令,而且它有一组独特的 r8-r14 寄存器,所以下次我们回到 FIQ 中断时,我们不需要推送/弹出堆。当然,它节省了一些周期,但是让更多的处理程序服务于一个 FIQ 也是不明智的,是的,FIQ 具有更高的优先级,但没有任何理由说它可以更快地处理中断,IRQ/FIQ 都以相同的 CPU 频率运行,所以它们必须以相同的速度运行。

于 2012-12-21T15:05:31.743 回答
-5

这可能是错误的。我所知道的是 FIQ 代表快速中断请求,而 IRQ 代表中断请求。从这些名称来看,我猜 FIQ 将比 IRQ 更快地处理(抛出?)。它可能与处理器的设计有关,其中 FIQ 会比 IRQ 更快地中断进程。如果我错了,我深表歉意,但我通常会进行更高级别的编程,我现在只是在猜测。

于 2009-06-19T04:50:34.413 回答