patislav
patislav

Reputation: 1

Soft system restart with use of EWI - early wakeup interrupt

I have an STM32F303 application which I would like to protect from unexpected firmware response by watchdog, but I can't pass through reset because setting peripherals to defaults would cause a catastrophic failure of HW around. Leaving peripherals at their state keeps application running without control for some time ( max 10 ms ), but it is not critical.

By studying of reference manual I got an idea to use EWI of WWDG which is triggered one step before system reset. Interrupt handler would do some checks and set some flags. I presume, that reason for this interrupt would be something like infinite loop which is a result of some unexpected condition. Thus this handler can't return to place which left. My idea is to replace return addres and to return to main function which based on flags set by handler performs system check, system reinicialization and locks fedback loop while application is still running.

Do you have an idea how to return from interrupt to specific addres or function?

The closest hint I have been able to find so far is here: Return Address from Interrupt in STM32F

It explains some details about return address from interrupt, but it doesn't seem to be complete story.

Edit: I've been continuing in digging in internet and I found this, which is the closest so far: https://interrupt.memfault.com/blog/cortex-m-hardfault-debug#recovering-from-a-fault

There is written: ...you may want to recover the system from a fault without rebooting it. That is purpose of my question.

I've been trying to implement the code, but there is some assembler incompatibility. In code

#define HARDFAULT_HANDLING_ASM(_x)
__asm volatile(
"tst lr, #4 \n"
"ite eq \n"
"mrseq r0, msp \n"
"mrsne r0, psp \n"
"b my_fault_handler_c \n"
)

it generates an error: #20: identifier "lr" is undefined. It doesn't make sense. In-built assembler doesn't know register names? After many experiments I reached to this:

my_fault_handler_c((sContextStateFrame*)(__current_sp() + 8 ));

__current_sp() replaces part

  tst lr, #4
  ite eq
  mrseq r0, msp
  mrsne r0, psp

but it isn't the same code. Then my_fault_handler_c is called like regular C function. Offset to SP is because compiler does puch {r4,lr} at ISR begin.

Simulation works but I'm not sure if getting of SP pointer like this is correct.

I'm using ARM compiler 5, build 422.

Upvotes: 0

Views: 21

Answers (0)

Related Questions