Monday, December 17, 2012

CortexM exception context

You can get exception context inside exception handler from memory. On Cortex M cores the context is pushed on stack. I have prepared the struct type with layout equal to the exception context. The context is available by assigning the address of context in memory to local pointer to variable of prepared struct type.

The example bellow was made for GCC compiler where you can easily specify local variable as register. This is unnecessary for local pointer variable but must be done for LR which holds information about exception context. Notice the naked attribute to handler function. It is needed so that the handler has no function prologue which could change SP. SP (main or process) actually holds the address of the exception context.

For easier debugging the software breakpoint is added at the end of handler and automatic handler catch functionality can be disabled so that CPU stops at breakpoint (not on handler entry).

typedef struct
  unsigned long m_dwExR0;
  unsigned long m_dwExR1;
  unsigned long m_dwExR2;
  unsigned long m_dwExR3;
  unsigned long m_dwExR12;
  unsigned long m_dwExLR;
  unsigned long m_dwExPC;
  unsigned long m_dwExPSR;

__attribute__( ( naked ) )
void HardFaultHandler()
  register SCortexM3ExContext * psCortexM3ExContext __asm("r0");
  register unsigned long dwLR __asm("lr");

  if ( dwLR & 4 )
    asm(" mrs r0, psp");
    asm(" mrs r0, msp");

  asm(" BKPT");
  while ( 1 );

Wednesday, December 12, 2012

Cortex exceptions entry and return

There is a difference in exception handling on CortexM and CortexR/A cores. You can find details in ARM Architecture Reference Manuals (2 documents - separate for M and R/A).

Exception entry

Cortex M

The addresses of exception (interrupt) handlers must be listed in vector table at address specified in VTOR register. Each exception (interrupt) has predefined offset location in vector table. Be sure to have LSB set in vector table entry values (denoting THUMB destination).

Cortex R and A

32 bit jump instructions with destination address of corresponding handler functions must be listed from address 0x00000000 or 0xFFFF0000 or VBAR or HVBAR  based on SCTLR.V bit, Security Extensions and Virtualization Extensions implementation and settings. Be sure to use correct branch instruction based on destination handler THUMB or ARM state.

Exception return

Cortex M

Exception  return is detected by writing a value with bits 31 .. 28 set (0xFxxxxxxx) to PC (R15). Conveniently the appropriate value is written to LR (R14) when the exception is taken. So basically no extra care is needed when returning from handler. Jump to LR as for return from subroutine is enough.

Cortex R and A

Exception return is done with special instruction based on architectue version and privilege level. Possible instructions are SUBS, MOVS, RFE, LDM and ERET.
With GCC the handler functions can be decorated with attribute denoting that it is an exception handler. GCC will then generate proper return instructions in function epilogue. Possible entries for GCC interrupt attribute are: IRQ, FIQ, SWI, ABORT and UNDEF.