CODE
thumb
public hal_eoi_jump
hal_eoi_jump: cpsid I
ldr R1, =sfe(HANDLER_STACK)
msr MSP, R1
mrs R1, PSP
orr R0, R0, #1
str R0, [R1, #lpc_ctx_PC]
str R0, [R1, #lpc_ctx_LR]
mov R0, #(1<<24)
str R0, [R1, #lpc_ctx_PSR]
ldr LR, =0xFFFFFFFD
bx LR
public hal_eoi_jump
hal_eoi_jump: cpsid I
ldr R1, =sfe(HANDLER_STACK)
msr MSP, R1
mrs R1, PSP
orr R0, R0, #1
str R0, [R1, #lpc_ctx_PC]
str R0, [R1, #lpc_ctx_LR]
mov R0, #(1<<24)
str R0, [R1, #lpc_ctx_PSR]
ldr LR, =0xFFFFFFFD
bx LR
Это такой себе аналог BSOD - при возникновении аварийной ситуации в обработчике прерываний вызывается эта функция с адресом в R0 куда передать управление приложению. RTOS при этом неживая уже, поэтому просто надо жестко выйти из исключения, все что нужно переинициализировать и уйти в спящий режим.
Этот код около года беспроблемно работал на LPC17, а вот на STM32 изредка вываливал Hard Fault, причем на инструкции куда осуществлялся возврат - точка входа режима приложения. Оказалось что из-за особенностей реализации софта на STM32 эта функция иногда вызывалась из вложенного обработчика прерываний - и сразу за bx LR следовало HF. Если вызов был не из вложенного обработчика - то все было OK. Я попробовал вызвать функцию из вложенного обработчика на LPC17 - и тоже получился Hard Fault. В-общем, имхо, ядро Кортекс считает уровни вложений - хотя странно, из документации этого не следует и вроде бы для реализации предлагаемой Кортексом схемы прерываний это не нужно.