diff --git a/Makefile b/Makefile index 5afef93..a906bad 100644 --- a/Makefile +++ b/Makefile @@ -95,7 +95,9 @@ endif ifeq ($(TARGET),F303) USE_FPU = hard USE_PROCESS_STACKSIZE = 0x480 - USE_EXCEPTIONS_STACKSIZE = 0x200 + # The fault reporter renders through the LCD/printf stack. Reserve room for + # its assembly veneer, an extended exception frame, and a nested ISR frame. + USE_EXCEPTIONS_STACKSIZE = 0x400 endif # diff --git a/docs/CHIBIOS_21_11_5_PORT.md b/docs/CHIBIOS_21_11_5_PORT.md index c1bb16a..8caf507 100644 --- a/docs/CHIBIOS_21_11_5_PORT.md +++ b/docs/CHIBIOS_21_11_5_PORT.md @@ -34,6 +34,8 @@ this port is marked ready. explicitly. ChibiOS 21.11.x no longer adds it automatically; omitting it promotes unsuffixed sweep constants to software double precision and causes a measurable self-test sweep regression. +- Split the F303 HardFault entry into an assembly-only MSP/PSP veneer and an + ordinary non-returning C reporter, while reserving a 1 KiB exception stack. ## Build diff --git a/main.c b/main.c index 745074a..119afa6 100644 --- a/main.c +++ b/main.c @@ -3451,8 +3451,35 @@ int main(void) } } -/* The prototype shows it is a naked function - in effect this is just an -assembly function. */ +#ifdef TINYSA4 +void hard_fault_handler_c(uint32_t *sp, const uint32_t *callee) + __attribute__((noreturn, noinline)); +void HardFault_Handler(void) __attribute__((naked)); + +void HardFault_Handler(void) +{ + __asm volatile( + "tst lr, #4\n" + "ite eq\n" + "mrseq r0, msp\n" + "mrsne r0, psp\n" + "sub sp, sp, #32\n" + "str r4, [sp, #0]\n" + "str r5, [sp, #4]\n" + "str r6, [sp, #8]\n" + "str r7, [sp, #12]\n" + "mov r2, r8\n" + "str r2, [sp, #16]\n" + "mov r2, r9\n" + "str r2, [sp, #20]\n" + "mov r2, r10\n" + "str r2, [sp, #24]\n" + "mov r2, r11\n" + "str r2, [sp, #28]\n" + "mov r1, sp\n" + "b hard_fault_handler_c\n"); +} +#else void HardFault_Handler(void); void hard_fault_handler_c(uint32_t *sp) __attribute__((naked)); @@ -3465,22 +3492,27 @@ void HardFault_Handler(void) __asm volatile("mrs %0, psp \n\t" : "=r"(sp)); hard_fault_handler_c(sp); } +#endif +#ifdef TINYSA4 +void hard_fault_handler_c(uint32_t *sp, const uint32_t *callee) +#else void hard_fault_handler_c(uint32_t *sp) +#endif { #ifdef TINYSA4 uint32_t r0 = sp[0]; uint32_t r1 = sp[1]; uint32_t r2 = sp[2]; uint32_t r3 = sp[3]; - register uint32_t r4 __asm("r4"); - register uint32_t r5 __asm("r5"); - register uint32_t r6 __asm("r6"); - register uint32_t r7 __asm("r7"); - register uint32_t r8 __asm("r8"); - register uint32_t r9 __asm("r9"); - register uint32_t r10 __asm("r10"); - register uint32_t r11 __asm("r11"); + uint32_t r4 = callee[0]; + uint32_t r5 = callee[1]; + uint32_t r6 = callee[2]; + uint32_t r7 = callee[3]; + uint32_t r8 = callee[4]; + uint32_t r9 = callee[5]; + uint32_t r10 = callee[6]; + uint32_t r11 = callee[7]; uint32_t r12 = sp[4]; uint32_t lr = sp[5]; uint32_t pc = sp[6]; @@ -3538,4 +3570,3 @@ void hard_fault_handler_c(uint32_t *sp) } -