【问题标题】:Temporarily disable interrupts on ARM暂时禁用 ARM 上的中断
【发布时间】:2016-10-13 11:38:40
【问题描述】:

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

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

我该怎么做?

【问题讨论】:

    标签: arm interrupt armv7 tms570


    【解决方案1】:

    要在 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
    

    【讨论】:

    • 值得注意的是,在 Cortex-R 上,根据您所处的模式,有各种不同的 PSR 寄存器。您需要确保使用正确的寄存器!请参阅 Cortex-R 技术参考手册,
    • @RealtimeRik 各种?当然,APSR 是“可从用户模式访问的 CPSR 部分”的别名,但它仍然是完全相同的寄存器。您不会考虑 M 配置文件,是吗(确实有 3 个单独的 PSR,以及它们所有可能组合的别名)?
    • 不,我在想 Cortex-R。如果您在用户模式下执行所有这些操作,那么 CPSR 将保持不变。但是,例如,您是在中断或主管模式下访问它,那么它会有所不同。
    • @RealtimeRik 无论如何,禁用中断与用户模式无关。 CPSR 是 当前 程序状态 - 除了 M 字段中的值之外,模式之间没有“不同”,这是 确定 您处于哪种模式首先!
    【解决方案2】:

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

    【讨论】:

    • 感谢您的回答。一般来说,你是对的,但是如果由于某种原因中断已经被禁用怎么办?然后,当这可能不是真正想要的时候,我会在最后启用它们。所以保存CPSR并将相关部分恢复为suggested by Notlikethat似乎是至关重要的。
    • 我只发布了一个字符串。实际上,我会进行嵌套级别计数。此外,如果您在中断内部,则不需要禁用中断。
    • 这取决于我是否知道我在中断中。假设我有类似队列框架之类的东西,并且我需要确保更改以原子方式发生。然后我需要在开始时无条件地禁用中断并重新建立以前的情况,因为库函数不知道它是否从中断中调用。
    • #define MODE_BITS 0x1F #define FIQ_MODE 0x11 #define IRQ_MODE 0x12 static INLINE bool isFromInterrupt (void) { register uint32_t cpsr = getCPSRValue ();注册 uint32_t 模式 = cpsr & MODE_BITS;返回(模式 == FIQ_MODE)|| (模式 == IRQ_MODE); }
    • 这似乎比我只存储 CPSR 并部分恢复它的其他解决方案复杂得多。
    猜你喜欢
    • 2012-11-29
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 2016-02-25
    • 2012-12-25
    相关资源
    最近更新 更多