Временно отключить прерывания на ARM
Я начинаю работать с платформой ARM (особенно с семейством TI TMS570).
У меня есть код с критическими областями, где я не хочу, чтобы происходило исключение. Поэтому я хочу сохранить флаги IRQ и FIR при входе в регионы и восстановить их при выходе.
Как я могу это сделать?
2 ответа
Чтобы временно замаскировать 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)