Hardfault CortexM re-handled irq

I’m try to re direct interrupts, but find that in certain situations I’m getting hard faults. I’ve essentially done the following:

#define VECTOR_MBR 0x20000000
#define VECTOR_OFFSET 16
uint32_t volatile __attribute__((section(".vector_mbr"))) vectorAddr = 0;
typedef void (*p_function)(void);
static void jump_to(int32_t irqn) {
  uint32_t *index = (uint32_t *)vectorAddr + VECTOR_OFFSET;
  p_function jumpFunc = (p_function)index[irqn];
  jumpFunc();
}
#if configUSE_MBR_FUNCTIONS == 1 /* vPortSVCHandler */
void SVC_Handler(void) {
  if (vectorAddr == 0) {
    SVC_Handler_MBR();
  } else {
    jump_to(SVCall_IRQn);
  }
}
#endif

#if configUSE_MBR_FUNCTIONS == 1 /* xPortPendSVHandler */
void PendSV_Handler(void) {
  if (vectorAddr == 0) {
    PendSV_Handler_MBR();
  } else {
    jump_to(PendSV_IRQn);
  }
}

void SysTick_Handler(void) { /* xPortSysTickHandler */
  if (vectorAddr == 0) {
    SysTick_Handler_MBR();
  } else {
    jump_to(SysTick_IRQn);
  }
}
#endif

and in FreeRTOS config

    #if configUSE_MBR_FUNCTIONS == 1
    void SysTick_Handler(void);
    #define xPortSysTickHandler     SysTick_Handler_MBR
    #else
    #define xPortSysTickHandler     SysTick_Handler
    #endif

#if configUSE_MBR_FUNCTIONS == 1
#define xPortPendSVHandler PendSV_Handler_MBR
#define vPortSVCHandler SVC_Handler_MBR
#define xPortSysTickHandler SysTick_Handler_MBR
#else
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
#endif

Is there an obvious reason this would cause a hard fault, or do I need to look elsewhere?

In testing here, vectorAddr == 0 and I know its calling the _MBR functions.

FreeRTOSConfig.h (8.6 KB)

Attached my config. configASSERT is defined, etc.

One big issue is that when you enter your PendSV_Handler function, the complier is going to save some registers on the stack and thus not match the expected state of the handler.

You might be able to write a handler in assembly that uses just the pre-saved registers (or saves and restores registers needed) and makes the decision and JUMPS to the FreeRTOS handler, so it is entered as if the vector just went to it.

Agree with Richard. For at least PendSV you’ll want to write the re-vectoring in assembly language and use only R0 - R3. Otherwise you can get context corruption.