暂时禁用 ARM 上的中断

Temporarily disable interrupts on ARM

我开始使用 ARM 平台(特别是 TI TMS570 系列)。

我有一些关键区域的代码,我不希望在这些区域发生异常。所以我想在进入区域时保存 IRQ 和 FIR 启用标志,并在退出时恢复它们。

我该怎么做?

要在 CPU 临时屏蔽 IRQ 和 FIQ,ARMv7 的最佳选择是使用 cps:

// assembly code assuming interrupts unmasked on entry

cpsid if  // mask IRQ and FIQ
...       // do critical stuff
cpsie if  // unmask

一些编译器提供了一组 __disable_irq() 等可从 C 代码使用的内在函数,但对于其他编译器(如 GCC),这将是一个下降到汇编的情况。

如果您希望关键部分是嵌套的、可重入的、进入中断处理程序或任何其他需要恢复以前状态的东西,而不是最后无条件地取消屏蔽,那么您需要将该状态复制出CPSR 在屏蔽任何东西之前,然后在退出时恢复它。在这一点上,取消屏蔽可能最终更容易处理 CPSR 的直接读取-修改-写入的老式方法。这是我的一个想法:

// int enter_critical_section(void);
enter_critical_section:
mrs r0, cpsr
cpsid if
and r0, r0, #0xc0  // leave just the I and F flags
bx lr

// void leave_critical_section(int flags);
leave_critical_section:
mrs r1, cpsr
bic r1, r1, r0
msr cpsr_c, r1
bx lr

您可以使用 _disable_interrupt_();_enable_interrupt_();来自 Halcogen 生成的代码 (sys_core.h)