Для временного маскирования прерываний и FIQs на CPU, самый хороший вариант для 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
Спасибо! Выглядит очень хорошо. Я попробую это. – glglgl
Стоит отметить, что на Cortex-R существуют различные различные регистры PSR в зависимости от того, в каком режиме вы находитесь. Вам нужно убедиться, что вы используете правильный! См. Технические справочные руководства Cortex-R, –
@RealtimeRik Разное? Конечно, APSR является псевдонимом для «частей CPSR, доступных из пользовательского режима», но он по-прежнему является тем же самым регистром. Вы не думаете о M-профиле, вы (у которого есть 3 отдельных PSR, плюс псевдонимы для всех возможных комбинаций из них)? – Notlikethat