17.5 Interrupt Service Routine Context Switching
When using Cortex-M devices, the hardware saves and restores the argument registers (r0 to r3), the IP register (r12) the link register (r14), the return address, and the program status registers when the interrupt occurs and returns. Other registers must be preserved by the interrupt handler function, as with any other function. The compiler will do this automatically for C functions. If you write your own handler in assembly, be sure to follow the procedure call standard.
It is possible for other exceptions to occur during the context switch. The work for this is handled in hardware. Details of this can be found in the appropriate architecture reference manual, but in essence, the context switching does not occur twice. Instead, the higher priority interrupt is run with the other interrupt set to pending.
When targeting Cortex-A devices, the compiler must generate application code to save and
restore the device context; however the Floating-point Unit (FPU) registers are never
saved by interrupt handlers. Applications on these devices that need to use the FPU from
an interrupt context require bespoke interrupt handlers. Consider writing the interrupt
handler in assembly code, having them push all the registers that need to be saved, call
the function for the handler, restore the registers, and then return. This assembly
wrapper function would need to be applied to every interrupt handler (or at least those
that use FPU registers). In this case, C functions should not set the
interrupt
attribute. Registers r0-r12, r14, d0-d7, d16-d32, and the
status registers must be saved if they have been used in the handler. This is
potentially a large number of registers that need to be saved, which would require a
significant amount of stack space to have them preserved and a significant amount of
time for that preservation code to execute.