From 60d15b8c0723bac1c1f2d63228fd41fe24cce67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Mon, 10 Apr 2023 22:40:02 +0200 Subject: [PATCH] add fancy hardfault handler, increase heater stack size --- Core/Src/Gui/app_gui.c | 1 + Core/Src/app_temp.c | 2 +- Core/Src/freertos.c | 2 +- Core/Src/stm32f1xx_it.c | 178 +++++++++++++++++++++++++++++++++++++--- Lib/snprintf/snprintf.c | 28 ++++++- 5 files changed, 194 insertions(+), 17 deletions(-) diff --git a/Core/Src/Gui/app_gui.c b/Core/Src/Gui/app_gui.c index d4af5c7..0d29f05 100644 --- a/Core/Src/Gui/app_gui.c +++ b/Core/Src/Gui/app_gui.c @@ -121,6 +121,7 @@ void app_task_gui(void *argument) { /** Switch to a different screen handler. * If "init" is true, immediately call it with the init event. */ void switch_screen(screen_t pScreen, bool init) { + PRINTF("Screen = %p, init=%d\r\n", pScreen, init); s_app.initial_pushed = s_app.pushed; s_app.screen = pScreen; // clear the union field diff --git a/Core/Src/app_temp.c b/Core/Src/app_temp.c index 431fa73..a0ac79b 100644 --- a/Core/Src/app_temp.c +++ b/Core/Src/app_temp.c @@ -313,7 +313,7 @@ void app_temp_sample() float y = s_analog.cal_a * sum + s_analog.cal_b; float actual_temp = val_to_c(y); - PRINTF("T raw %f %f -> comp %f, temp %f°C\r\n", sum, y, actual_temp); + PRINTF("T raw %f -> comp %f, temp %f°C\r\n", sum, y, actual_temp); s_analog.oven_temp = actual_temp; s_analog.oven_temp_raw = sum; diff --git a/Core/Src/freertos.c b/Core/Src/freertos.c index 28176cf..f0608ed 100644 --- a/Core/Src/freertos.c +++ b/Core/Src/freertos.c @@ -66,7 +66,7 @@ const osThreadAttr_t mainTsk_attributes = { }; /* Definitions for heaterTsk */ osThreadId_t heaterTskHandle; -uint32_t heaterTskBuffer[ 128 ]; +uint32_t heaterTskBuffer[ 256 ]; osStaticThreadDef_t heaterTskControlBlock; const osThreadAttr_t heaterTsk_attributes = { .name = "heaterTsk", diff --git a/Core/Src/stm32f1xx_it.c b/Core/Src/stm32f1xx_it.c index 2f90d89..2043de2 100644 --- a/Core/Src/stm32f1xx_it.c +++ b/Core/Src/stm32f1xx_it.c @@ -26,6 +26,8 @@ /* USER CODE BEGIN Includes */ #include "app_temp.h" #include "app_knob.h" +#include "app_heater.h" +#include /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -89,20 +91,174 @@ void NMI_Handler(void) /* USER CODE END NonMaskableInt_IRQn 1 */ } + +#define VERBOSE_HARDFAULT 1 + + +#if VERBOSE_HARDFAULT +void __attribute__((used)) HardFault_DumpRegisters(const uint32_t *origStack, uint32_t lr_value) +{ +/* These are volatile to try and prevent the compiler/linker optimising them +away as the variables never actually get used. If the debugger won't show the +values of the variables, make them global my moving their declaration outside +of this function. */ + volatile uint32_t stacked_r0; + volatile uint32_t stacked_r1; + volatile uint32_t stacked_r2; + volatile uint32_t stacked_r3; + volatile uint32_t stacked_r12; + volatile uint32_t stacked_lr; /* Link register. */ + volatile uint32_t stacked_pc; /* Program counter. */ + volatile uint32_t stacked_psr;/* Program status register. */ + +#if (__CORTEX_M >= 3) + uint32_t cfsr, hfsr, dfsr; + + uint32_t bus_fault_address; + uint32_t memmanage_fault_address; + + bus_fault_address = SCB->BFAR; + memmanage_fault_address = SCB->MMFAR; + cfsr = SCB->CFSR; + hfsr = SCB->HFSR; + dfsr = SCB->DFSR; +#endif + + stacked_r0 = origStack[0]; + stacked_r1 = origStack[1]; + stacked_r2 = origStack[2]; + stacked_r3 = origStack[3]; + stacked_r12 = origStack[4]; + stacked_lr = origStack[5]; + stacked_pc = origStack[6]; + stacked_psr = origStack[7]; + + app_heater_emergency_shutdown(); + +#define BS(reg, pos, str) (((reg)&(1<<(pos)))?(str" "):"") +#define REDPTR(val) (((val)&0xFF000000) != 0x08000000?"\033[31m":"\033[32m") + + PRINTF("\r\n*** HARD FAULT ***\r\n\r\n"); + PRINTF("- Stack frame:\r\n"); + PRINTF(" R0 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r0); + PRINTF(" R1 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r1); + PRINTF(" R2 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r2); + PRINTF(" R3 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r3); + PRINTF(" R12 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r12); + PRINTF(" LR = %s0x%08"PRIX32"\033[m\r\n", REDPTR(stacked_lr), stacked_lr); + PRINTF(" PC = %s0x%08"PRIX32"\033[m\r\n", REDPTR(stacked_pc), stacked_pc); + PRINTF(" PSR = \033[36m0x%08"PRIX32"\033[m", stacked_psr); + uint32_t exc = stacked_psr & 0x3F; + PRINTF(" [ %s%s%s%s%s ]\r\n", + BS(stacked_psr, 31, "N"), + BS(stacked_psr, 30, "Z"), + BS(stacked_psr, 29, "C"), + BS(stacked_psr, 28, "V"), + //BS(stacked_psr, 24, "T"), - thumb, always ON + + (exc==0)?"Thread": + (exc==2)?"NMI": + (exc==3)?"HardFault": + (exc==11)?"SVCall": + (exc==14)?"PendSV": + (exc==15)?"SysTick": + (exc>=16)?"IRQ":"Unknown" + ); + +#if (__CORTEX_M >= 3) + PRINTF("\r\n- FSR/FAR:\r\n"); + PRINTF(" CFSR = \033[36m0x%08"PRIX32"\033[m\r\n", cfsr); + PRINTF(" UsageFault: \033[31;1m%s%s%s%s%s%s%s\033[m\r\n" + " BusFault: \033[31;1m%s%s%s%s%s%s%s%s\033[m\r\n" + " MemFault: \033[31;1m%s%s%s%s%s%s%s\033[m\r\n", + BS(cfsr, 0, "IAccViol"), + BS(cfsr, 1, "DAccViol"), + BS(cfsr, 3, "MUnstkErr"), + BS(cfsr, 4, "MStkErr"), + BS(cfsr, 5, "MLSPErr(FPU)"), + BS(cfsr, 7, "MMArValid"), + ((cfsr&0xFF)?"":"\033[m- "), + + BS(cfsr, 8, "IBusErr"), + BS(cfsr, 9, "PreciseErr"), + BS(cfsr, 10, "ImpreciseErr"), + BS(cfsr, 11, "UnstkErr"), + BS(cfsr, 12, "StkErr"), + BS(cfsr, 13, "LSPErr"), + BS(cfsr, 15, "BFArValid"), + ((cfsr&0xFF00)?"":"\033[m- "), + + BS(cfsr, 16, "UndefInstr"), + BS(cfsr, 17, "InvState"), + BS(cfsr, 18, "InvPC"), + BS(cfsr, 19, "NoCP"), + BS(cfsr, 24, "Unaligned"), + BS(cfsr, 25, "Div0"), + ((cfsr&0xFFFF0000)?"":"\033[m- ") + ); + + PRINTF(" HFSR = \033[36m0x%08"PRIX32"\033[m", hfsr); + PRINTF(" [ %s%s%s]\r\n", + BS(hfsr, 31, "DebugEvt"), + BS(hfsr, 30, "Forced"), + BS(hfsr, 1, "VectTbl") + ); + + PRINTF(" DFSR = \033[36m0x%08"PRIX32"\033[m", dfsr); + PRINTF(" [ %s%s%s%s%s]\r\n", + BS(dfsr, 0, "Halted"), + BS(dfsr, 1, "Bkpt"), + BS(dfsr, 2, "DWtTrap"), + BS(dfsr, 3, "VCatch"), + BS(dfsr, 4, "External") + ); + + if (cfsr & 0x0080) PRINTF(" MMFAR = \033[33m0x%08"PRIX32"\033[m\r\n", memmanage_fault_address); + if (cfsr & 0x8000) PRINTF(" BFAR = \033[33m0x%08"PRIX32"\033[m\r\n", bus_fault_address); + PRINTF("\r\n- Misc\r\n"); + PRINTF(" LR/EXC_RETURN= %s0x%08"PRIX32"\033[m\n", REDPTR(lr_value), lr_value); +#endif + + while (1); +} +#endif + /** - * @brief This function handles Hard fault interrupt. - */ -void HardFault_Handler(void) +* @brief This function handles Hard fault interrupt. +*/ +void __attribute__((naked)) HardFault_Handler(void) { - /* USER CODE BEGIN HardFault_IRQn 0 */ - PUTS("HardFault_Handler\r\n"); +#if VERBOSE_HARDFAULT + // __asm volatile +// ( +// " tst lr, #4 \n" +// " ite eq \n" +// " mrseq r0, msp \n" +// " mrsne r0, psp \n" +// " ldr r1, [r0, #24] \n" +// " mov r2, lr \n" +// " ldr r3, handler2_address_const \n" +// " bx r3 \n" +// " handler2_address_const: .word HardFault_DumpRegisters \n" +// ); +// + __asm volatile( ".syntax unified\n" + "MOVS R0, #4 \n" + "MOV R1, LR \n" + "TST R0, R1 \n" + "BEQ _MSP \n" + "MRS R0, PSP \n" + "B HardFault_DumpRegisters \n" + "_MSP: \n" + "MRS R0, MSP \n" + "B HardFault_DumpRegisters \n" + ".syntax divided\n") ; + +#else app_emergency_stop(); - - /* USER CODE END HardFault_IRQn 0 */ - while (1) { - /* USER CODE BEGIN W1_HardFault_IRQn 0 */ - /* USER CODE END W1_HardFault_IRQn 0 */ - } + PRINTF("*** HARD FAULT ***\r\n\r\n"); + while (1); +#endif } /** diff --git a/Lib/snprintf/snprintf.c b/Lib/snprintf/snprintf.c index bb75b1a..5df9eae 100644 --- a/Lib/snprintf/snprintf.c +++ b/Lib/snprintf/snprintf.c @@ -29,6 +29,10 @@ #define my_malloc(len) pvPortMalloc((len)) #define my_free(p) vPortFree((p)) +// Use a static buffer to avoid allocating for every printf! +#define S_PRINTF_BUF_LEN 200 +static char s_printf_buf[S_PRINTF_BUF_LEN]; + // Toggle features #define size_t size_t /* normally: int, unsigned */ #undef HAVE_LONG_DOUBLE @@ -733,9 +737,11 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, // leading zeros in the fractional part fzeropad = 0; fzerocnt = max - 1; - while (fracpart < POW10(fzerocnt)) { - fzeropad++; - fzerocnt--; + if (fzerocnt > 0) { + while (fracpart < POW10(fzerocnt)) { + fzeropad++; + fzerocnt--; + } } do { temp = fracpart; @@ -800,8 +806,9 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, zpadlen = 0; } - while (fzeropad-- > 0) { + while (fzeropad > 0) { dopr_outch(buffer, currlen, maxlen, '0'); + fzeropad--; } while (fplace > 0) { @@ -892,6 +899,18 @@ int printf(const char *format, ...) va_list ap; int ret; + va_start(ap, format); + ret = vsnprintf(s_printf_buf, S_PRINTF_BUF_LEN, format, ap); + va_end(ap); + + PUTS(s_printf_buf); + + return ret; + +#if 0 + va_list ap; + int ret; + char *ptr = NULL; va_start(ap, format); @@ -906,6 +925,7 @@ int printf(const char *format, ...) my_free(ptr); return ret; +#endif } int vprintf(const char *format, va_list ap)