【问题标题】:Why FIQ need to be written in assembly not in C?为什么 FIQ 需要用汇编语言而不是 C 语言编写?
【发布时间】:2015-04-26 06:29:32
【问题描述】:

我正在研究 FIQ 在 ARM 上的工作原理,并发现 FIQ 应该始终用汇编而不是 C 编写,但不明白为什么?

我已经浏览了以下链接

http://comments.gmane.org/gmane.linux.ports.arm.kernel/14004

但仍然无法弄清楚为什么需要它?

谁能通过一些例子指出我在汇编中编写FIQ的必要性?

【问题讨论】:

  • 正如讨论中的最后两篇文章所指出的,这不是必需的,不这样做几乎没有意义。另请注意,讨论仅限于 Linux 上下文。
  • 一个问题是上下文切换回中断模式,可能是 IRQ, Supervisor, System, User, ... ,这需要特殊指令,但这些可以实现为内在函数或库调用.另一个问题是速度和利用 R8-R14 的影子副本,但编译器扩展可能会将这些用于声明为“FIQ”寄存器类型的变量。
  • 您的问题含糊不清。上面的讨论是针对 Linux 的。 2004 年,Linux 还没有 FIQ 堆栈。如果您自己设置,您可能拥有一个 FIQ 堆栈。实际上并不清楚您想要什么,也不清楚您尝试过什么。您可能不容易在“C”中处理 FIQ,就像 IRQ 一样,因为 ARM 向量表需要分支。您至少需要一个存根或“C”扩展和链接器魔术。理论上,使用 gcc 和一些扩展是可能的;至少要进行立即返回的 FIQ。您在互联网上阅读的内容并不总是正确的,而且通常取决于上下文。
  • 可能值得注意的是,FIQ 模式的 original 上下文支持无缓冲外设,其中数据仅在一定数量的周期内有效,并且内存足够慢,以至于当您将几个寄存器压入堆栈以保存它们时,您获取中断的设备数据已经丢失 - 在您甚至尝试读取它之前。因此增加了额外的存储寄存器。当然,那是 30 年前的事了,现代系统大不相同。
  • @Notlikethat Kudos,我刚知道第一个 arm 芯片是 30 年前的,并且支持 FIQ。

标签: c assembly arm interrupt-handling fiq


【解决方案1】:

我的猜测是基于此:

另外,用 C 语言编写 FIQ 代码有点困难,因为您缺少堆栈 :)

如果没有堆栈,则意味着编译器仅限于对所有变量使用寄存器,我不确定你会如何表达。

您可以将register 放在所有局部变量上,但这并不意味着编译器必须遵守。

在汇编中编写代码当然可以绕过这个限制,并且可以结合寄存器和全局状态来做事。

另请参阅this question's answers,了解有关普通中断和快速中断之间区别的更多信息。

【讨论】:

  • 如果没有堆栈,您也只有 5 个可以触摸的寄存器(好吧,如果您滥用 sp 和 lr,则为 7 个),因为您无处保存其他寄存器。尝试说服 C 编译器遵守这些规则;)
  • 我没有看到交换到特定于 FIQ 的堆栈的问题?只有一个 FIQ,所以应该不是问题。我实际上还没有尝试过 - 到目前为止,我已经设法用我的 FIQ 摆脱了汇编程序和 R8-13 :)
  • 远离处于中断状态的库。由于 FIQ 将中断正常的 IRQ 处理程序,其作者可能也认为其时间紧迫,因此需要使用快速、干净、精简的代码来编写高优先级中断,这与熟练的程序员所期望的完全一样。
  • 我真的不明白用 C 语言编写 FIQ,我们缺少堆栈吗?
  • 每个 ARM 模式都有自己的 R13 卷影副本(除了用户模式和系统模式共享同一组寄存器),因此在初始化期间,代码切换到每种模式并将该模式​​的 R13 设置为该模式的堆栈,因此每个模式,包括 FIQ,都有自己的堆栈。
【解决方案2】:

因为有什么意义,您使用额外的寄存器组来节省少数时钟周期来保存状态,然后使用 C 并完全浪费了这微小的成本节省?如果您对优化到那个级别不感兴趣,那么不要打扰 fiq,只需使用 irq。

【讨论】:

    猜你喜欢
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2010-12-24
    • 2011-03-20
    • 1970-01-01
    • 2014-09-03
    相关资源
    最近更新 更多