FIQ和IRQ中断系统有什么区别?

发布于 2024-07-24 03:59:14 字数 46 浏览 7 评论 0原文

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

I want to know the difference between FIQ and IRQ interrupt system in
any microprocessor, e.g: ARM926EJ.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

捎一片雪花 2024-07-31 03:59:14

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

在某种程度上,这使得两种中断模式之间的区别变得多余,并且许多系统根本不使用nFIQ,或者以类似于不可屏蔽(NMI)的方式使用它code>)在其他处理器上发现的中断(尽管 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。 由符合 ARM 的 ATPCS 过程调用标准的 C 编译器生成的代码将使用寄存器 r0-r3 作为临时值,并且不会生成正确的 cpsr 在函数末尾恢复返回代码。
  2. 所有中断控制器硬件通常位于 IRQ 引脚上。 仅当您有一个最高优先级中断源连接到 nFIQ 输入并且许多系统没有一个永久最高优先级源时,使用 FIQ 才有意义。 将多个源连接到 FIQ,然后让软件在它们之间划分优先级是没有价值的,因为这几乎消除了 FIQ 相对于 IRQ 的所有优势。

ARM calls FIQ the fast interrupt, with the implication that IRQ is normal priority. In any real system, there will be many more sources of interrupts than just two devices and there will therefore be some external hardware interrupt controller which allows masking, prioritization etc. of these multiple sources and which drives the interrupt request lines to the processor.

To some extent, this makes the distinction between the two interrupt modes redundant and many systems do not use nFIQ at all, or use it in a way analogous to the non-maskable (NMI) interrupt found on other processors (although FIQ is software maskable on most ARM processors).

So why does ARM call FIQ "fast"?

  1. FIQ mode has its own dedicated banked registers, r8-r14. R14 is the link register which holds the return address(+4) from the FIQ. But if your FIQ handler is able to be written such that it only uses r8-r13, it can take advantage of these banked registers in two ways:
    • One is that it does not incur the overhead of pushing and popping any registers that are used by the interrupt service routine (ISR). This can save a significant number of cycles on both entry and exit to the ISR.
    • Also, the handler can rely on values persisting in registers from one call to the next, so that for example r8 may be used as a pointer to a hardware device and the handler can rely on the same value being in r8 the next time it is called.
  2. FIQ location at the end of the exception vector table (0x1C) means that if the FIQ handler code is placed directly at the end of the vector table, no branch is required - the code can execute directly from 0x1C. This saves a few cycles on entry to the ISR.
  3. FIQ has higher priority than IRQ. This means that when the core takes an FIQ exception, it automatically masks out IRQs. An IRQ cannot interrupt the FIQ handler. The opposite is not true - the IRQ does not mask FIQs and so the FIQ handler (if used) can interrupt the IRQ. Additionally, if both IRQ and FIQ requests occur at the same time, the core will deal with the FIQ first.

So why do many systems not use FIQ?

  1. FIQ handler code typically cannot be written in C - it needs to be written directly in assembly language. If you care sufficiently about ISR performance to want to use FIQ, you probably wouldn't want to leave a few cycles on the table by coding in C in any case, but more importantly the C compiler will not produce code that follows the restriction on using only registers r8-r13. Code produced by a C compiler compliant with ARM's ATPCS procedure call standard will instead use registers r0-r3 for scratch values and will not produce the correct cpsr restoring return code at the end of the function.
  2. All of the interrupt controller hardware is typically on the IRQ pin. Using FIQ only makes sense if you have a single highest priority interrupt source connected to the nFIQ input and many systems do not have a single permanently highest priority source. There is no value connecting multiple sources to the FIQ and then having software prioritize between them as this removes nearly all the advantages the FIQ has over IRQ.
巡山小妖精 2024-07-31 03:59:14

FIQ快速中断 在某些 ARM 参考文献中通常称为软 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 条指令。 主代码需要轮询 FIQ r10 以确定缓冲区何时完成。 主(非中断代码)可以通过使用msr指令来传输和设置存储的FIQ寄存器,以切换到FIQ模式并传输非中断分组 R0-R7 到分组 R8-R13 寄存器。

通常 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 缓存更快。 寄存器速度很快。 如果您无法编写使用 6 个变量运行的例程,则 FIQ 不适合。 注意:如果您使用 16 位值,您可以使用 shiftsrotates 来双重使用某些寄存器,这些寄存器在 ARM 上是免费的。

显然FIQ更为复杂。 操作系统开发人员希望支持多个中断源。 客户对FIQ的要求会有所不同,他们常常意识到他们应该让客户自行部署。 通常对FIQ的支持是有限的,因为任何支持都可能会损害主要好处,速度

摘要

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

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

FIQ or fast interrupt is often referred to as Soft DMA in some ARM references.
Features of the FIQ are,

  1. Separate mode with banked register including stack, link register and R8-R12.
  2. Separate FIQ enable/disable bit.
  3. Tail of vector table (which is always in cache and mapped by MMU).

The last feature also gives a slight advantage over an IRQ which must branch.

A speed demo in 'C'

Some have quoted the difficulty of coding in assembler to handle the FIQ. gcc has annotations to code a FIQ handler. Here is an example,

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++;
    }
}

This translates to the following almost good assembler,

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

The assembler routine at 0x1c might look like,

   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.

A real UART probably has a ready bit, but the code to make a high speed soft DMA with the FIQ would only be 10-20 instructions. The main code needs to poll the FIQ r10 to determine when the buffer is finished. Main (non-interrupt code) may transfer and setup the banked FIQ registers by using the msr instruction to switch to FIQ mode and transfer non-banked R0-R7 to the banked R8-R13 registers.

Typically RTOS interrupt latency will be 500-1000 instructions. For Linux, it maybe 2000-10000 instructions. Real DMA is always preferable, however, for high frequency simple interrupts (like a buffer transfer), the FIQ can provide a solution.

As the FIQ is about speed, you shouldn't consider it if you aren't secure in coding in assembler (or willing to dedicate the time). Assembler written by an infinitely running programmer will be faster than a compiler. Having GCC assist can help a novice.

Latency

As the FIQ has a separate mask bit it is almost ubiquitously enabled. On earlier ARM CPUs (such as the ARM926EJ), some atomic operations had to be implemented by masking interrupts. Still even with the most advanced Cortex CPUs, there are occasions where an OS will mask interrupts. Often the service time is not critical for an interrupt, but the time between signalling and servicing. Here, the FIQ also has an advantage.

Weakness

The FIQ is not scalable. In order to use multiple FIQ sources, the banked registers must be shared among interrupt routines. Also, code must be added to determine what caused the interrupt/FIQ. The FIQ is generally a one trick pony.

If your interrupt is highly complex (network driver, USB, etc), then the FIQ probably makes little sense. This is basically the same statement as multiplexing the interrupts. The banked registers give 6 free variables to use which never load from memory. Register are faster than memory. Registers are faster than L2-cache. Registers are faster than L1-cache. Registers are fast. If you can not write a routine that runs with 6 variables, then the FIQ is not suitable. Note: You can double duty some register with shifts and rotates which are free on the ARM, if you use 16 bit values.

Obviously the FIQ is more complex. OS developers want to support multiple interrupt sources. Customer requirements for a FIQ will vary and often they realize they should just let the customer roll their own. Usually support for a FIQ is limited as any support is likely to detract from the main benefit, SPEED.

Summary

Don't bash my friend the FIQ. It is a system programers one trick against stupid hardware. It is not for everyone, but it has its place. When all other attempts to reduce latency and increase ISR service frequency has failed, the FIQ can be your only choice (or a better hardware team).

It also possible to use as a panic interrupt in some safety critical applications.

人间☆小暴躁 2024-07-31 03:59:14

现代 ARM CPU(以及其他一些 CPU)的一项功能。

来自专利:

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

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

A feature of modern ARM CPUs (and some others).

From the patent:

A method of performing a fast
interrupt in a digital data processor
having the capability of handling more
than one interrupt is provided. When a
fast interrupt request is received a
flag is set and the program counter
and condition code registers are
stored on a stack. At the end of the
interrupt servicing routine the return
from interrupt instructions retrieves
the condition code register which
contains the status of the digital
data processor and checks to see
whether the flag has been set or not.
If the flag is set it indicates that a
fast interrupt was serviced and
therefore only the program counter is
unstacked.

In other words, an FIQ is just a higher priority interrupt request, that is prioritized by disabling IRQ and other FIQ handlers during request servicing. Therefore, no other interrupts can occur during the processing of the active FIQ interrupt.

木槿暧夏七纪年 2024-07-31 03:59:14

Chaos 已经给出了很好的答案,但到目前为止尚未涵盖的另一点是 FIQ 位于向量表的末尾,因此通常/传统上只是在那里启动例程,而 IRQ 向量通常就是这样。 (即跳转到其他地方)。 在完整的存储和上下文切换之后立即避免额外的分支可以稍微提高速度。

Chaos has already answered well, but an additional point not covered so far is that FIQ is at the end of the vector table and so it's common/traditional to just start the routine right there, whereas the IRQ vector is usually just that. (ie a jump to somewhere else). Avoiding that extra branch immediately after a full stash and context switch is a slight speed gain.

柳若烟 2024-07-31 03:59:14

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

another reason is in case of FIQ, lesser number of register is needed to push in the stack, FIQ mode has R8 to R14_fiq registers

余罪 2024-07-31 03:59:14

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

FIQ is higher priority, and can be introduced while another IRQ is being handled. The most critical resource(s) are handled by FIQ's, the rest are handled by IRQ's.

眉黛浅 2024-07-31 03:59:14

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

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

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

I believe this is what you are looking for:

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

Essentially, FIQ will be of the highest priority with multiple, lower priority IRQ sources.

流星番茄 2024-07-31 03:59:14

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

FIQs are higher priority, no doubt, remaining points i am not sure..... FIQs will support high speed data transfer (or) channel processing, where high speed data processes is required we use FIQs and generally IRQs are used normal interrupt handlling.

无言温柔 2024-07-31 03:59:14

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

No any magic about FIQ. FIQ just can interrupt any other IRQ which is being served,this is why it is called 'fast'. The system reacts faster on these interrupts but the rest is the same.

独自←快乐 2024-07-31 03:59:14

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

It Depends how we design interrupt handlers, as FIQ is at last it may not need one branch instruction, also it has unique set of r8-r14 registers so next time we come back to FIQ interrupt we do not need to push/pop up the stack. Ofcourse it saves some cycles, but again it is not wise to have more handlers serving one FIQ and yes FIQ is having more priority but it is not any reason to say it handles the interrupt faster, both IRQ/FIQ run at same CPU frequency, So they must be running at same speed.

俯瞰星空 2024-07-31 03:59:14

如果您的用例不是关于执行速度而是关于延迟,那么将 FIQ 与用 C* 而不是汇编程序编写的服务例程 (ISR) 结合使用可能会产生比标准方法更精简的代码。 考虑一个需要以比其他几个不频繁任务的执行时间更低的延迟来执行的任务。

标准方法:不频繁任务的 IRQ 仅设置通知标志并返回,以便可以以低延迟服务频繁任务的 ISR。 在任何 ISR 之外,每当设置相应的标志时,就会完成不频繁任务的工作。

使用 FIQ,您不需要通知,但每个任务都将完全作为 ISR 运行。

*) 鉴于您的 C 编译器知道如何实现 FIQ ISR。 例如,引用 ARM 优化 C/C++ 编译器 v18.1.0.LTS 用户指南(修订版 R)

5.10.15 INTERRUPT Pragma使您能够直接使用 C 代码处理中断。 [...] 保存的寄存器和返回顺序取决于中断类型。

If your use case is not about speed of execution but latency, using FIQ with the servicing routine (ISR) written in C* instead of assembler may result in leaner code than the standard approach. Think of one task that needs to be executed with a lower latency than the execution time of each of several other infrequent tasks.

The standard approach: The IRQs for the infrequent tasks would only set notification flags and return, so that the frequent task's ISR can be served with low latency. Outside of any ISR, the work of the infrequent tasks is done whenever the corresponding flag is set.

Using FIQ, you would not need notifications, but each task would run fully as ISR.

*) Given that your C compiler knows how to implement FIQ ISRs. Citing, for example, ARM Optimizing C/C++ Compiler v18.1.0.LTS User's Guide (Rev. R):

5.10.15 The INTERRUPT Pragma enables you to handle interrupts directly with C code. [...] The registers that are saved and the return sequence depend upon the interrupt type.

倾城月光淡如水﹏ 2024-07-31 03:59:14

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

This may be wrong. All I know is that FIQ stands for Fast Interrupt Request and that IRQ stands for Interrupt Request. Judging from these names, I will guess that a FIQ will be handled(thrown?) faster than an IRQ. It probably has something to do with the design of the processor where an FIQ will interrupt the process faster than an IRQ. I apologize if I'm wrong, but I normally do higher level programming, I'm just guessing right now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文