Temporarily disable interrupts on ARM

梦想与她 提交于 2019-12-21 12:46:24

问题


I am starting working with the ARM platform (specifically the TI TMS570 family).

I have some code with critical regions where I don't want an exception to occur. So I want to save the IRQ and FIR enabled flags on entering the regions and restore them on exiting.

How do I do that?


回答1:


To temporarily mask IRQs and FIQs at the CPU, the nicest option for ARMv7 is to use cps:

// assembly code assuming interrupts unmasked on entry

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

Some compilers provide a set of __disable_irq() etc. intrinsics usable from C code, but for others (like GCC) it's going to be a case of dropping to assembly.

If you want critical sections to be nested, reentrant, taken in interrupt handlers or anything else which requires restoring the previous state as opposed to just uncondionally unmasking at the end, then you'll need to copy that state out of the CPSR before masking anything, then restore it on exit. At that point the unmasking probably ends up simpler to handle the old-fashioned way of a direct read-modify-write of the CPSR. Here's one idea off the top of my head:

// 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



回答2:


You can use _disable_interrupt_();_enable_interrupt_(); from Halcogen generated code (sys_core.h)



来源:https://stackoverflow.com/questions/40019929/temporarily-disable-interrupts-on-arm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!