diff --git a/Inc/HALAL/HALAL.hpp b/Inc/HALAL/HALAL.hpp index fe4684068..f1bb426b3 100644 --- a/Inc/HALAL/HALAL.hpp +++ b/Inc/HALAL/HALAL.hpp @@ -44,6 +44,8 @@ #include "HALAL/Models/BoardID/BoardID.hpp" #include "HALAL/Models/Concepts/Concepts.hpp" +#include "HALAL/HardFault/HardfaultTrace.h" +#include "HALAL/Benchmarking_toolkit/DataWatchpointTrace/DataWatchpointTrace.hpp" #ifdef STLIB_ETH #include "HALAL/Models/Packets/Packet.hpp" #include "HALAL/Models/Packets/Order.hpp" diff --git a/Inc/HALAL/HardFault/HardfaultTrace.h b/Inc/HALAL/HardFault/HardfaultTrace.h new file mode 100644 index 000000000..6fe45e4b0 --- /dev/null +++ b/Inc/HALAL/HardFault/HardfaultTrace.h @@ -0,0 +1,56 @@ +#ifndef __HARD_FAULT_TRACE + +#define __HARD_FAULT_TRACE +#include "stm32h7xx_ll_gpio.h" +#include "stm32h7xx_ll_bus.h" +#include "stm32h7xx_ll_tim.h" +#define METADATA_FLASH_ADDR (0x080DFD00) //Metadata pool flash address +#define HF_FLASH_ADDR (0x080C0000U) //Hard_fault_flash address +#define HF_FLAG_VALUE (0xFF00FF00U) //Flag to know if already is written information in the flash +#define METADATA_FLASH_SIZE (0X100U) +#define HARD_FAULT_FLASH_SIZE (0X200U) +#define CALL_TRACE_MAX_DEPTH 16 +typedef struct __attribute__((packed)) ContextStateFrame { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t return_address; + uint32_t xpsr; +} sContextStateFrame; + + +typedef struct __attribute__((packed)) HardFaultLog{ + uint32_t HF_flag; + sContextStateFrame frame; + union{ + uint32_t cfsr; + struct CfSrFields{ + uint8_t MMFSR; + uint8_t BFSR; + uint16_t UFSR; + }fields; + }CfsrDecode; + union{ + uint32_t Nothing_Valid; + uint32_t MMAR_VALID; + uint32_t BFAR_VALID; + }fault_address; + struct __attribute__((packed)){ + uint32_t depth; + uint32_t pcs[CALL_TRACE_MAX_DEPTH]; + }CallTrace; +}HardFaultLog; // 112 bytes this estructure + + +#ifdef __cplusplus +extern "C" { +#endif +void Hard_fault_check(void); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/STM32H723ZGTX_FLASH.ld b/STM32H723ZGTX_FLASH.ld index 4e1345425..16f605035 100644 --- a/STM32H723ZGTX_FLASH.ld +++ b/STM32H723ZGTX_FLASH.ld @@ -35,6 +35,7 @@ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ +_sstack = ORIGIN(DTCMRAM); _estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM/DTCM */ _Min_Heap_Size = 0x200; /* required amount of heap */ @@ -82,6 +83,8 @@ SECTIONS .text : { . = ALIGN(4); + _stext = .; + *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ @@ -104,6 +107,14 @@ SECTIONS . = ALIGN(4); } >FLASH + .hardfault_stack (NOLOAD) : /*Stack memory to avoid memfault inside hardfault handler*/ + { + . = ALIGN(8); + _hf_stack_start = .; + . += 0x400; /* 1 KB */ + _hf_stack_end = .; + } >DTCMRAM + .ARM.extab (READONLY): { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM (READONLY): { __exidx_start = .; @@ -184,6 +195,13 @@ SECTIONS the sections below it would try to be placed afterwards thus overflowing the FLASH */ + + .hardfault_log 0x080C0000 : + { + KEEP(*(.hardfault_log)) + . = . + 0x200; + } >FLASH + .metadata_pool : { . = ABSOLUTE(0x080DFD00); @@ -192,6 +210,7 @@ SECTIONS KEEP(*(.metadata_pool)) . += 0x100; } >FLASH + /* Uninitialized data section */ . = ALIGN(4); .bss (NOLOAD) : diff --git a/Src/HALAL/HardFault/HardfaultTrace.c b/Src/HALAL/HardFault/HardfaultTrace.c new file mode 100644 index 000000000..8f5a9ad45 --- /dev/null +++ b/Src/HALAL/HardFault/HardfaultTrace.c @@ -0,0 +1,69 @@ +#include "HALAL/HardFault/HardfaultTrace.h" +#ifdef NUCLEO +#define REPS 200000 +#endif + +#ifdef BOARD +#define REPS 600000 // Three times faster because the board frequency +#endif + +extern GPIO_TypeDef* ports_hard_fault[]; +extern uint16_t pins_hard_fault[]; +extern uint8_t hard_fault_leds_count; + +static void LED_Blink(); +static void LED_init(void); +static void EnableGPIOClock(GPIO_TypeDef* port); +static void InitGPIO_Output(GPIO_TypeDef* port,uint16_t pin); +static void delay(); + +__attribute__((optimize("O0"))) +static void delay(){ + for(volatile uint64_t i = 0; i < REPS; i++){ + __NOP(); + } +} +static void LED_Blink(){ + for(volatile int i = 0; i < hard_fault_leds_count;i++){ + LL_GPIO_TogglePin(ports_hard_fault[i],pins_hard_fault[i]); + } + delay(); +} +static void LED_init(void){ + for(int i = 0; i < hard_fault_leds_count;i++){ + EnableGPIOClock(ports_hard_fault[i]); + InitGPIO_Output(ports_hard_fault[i],pins_hard_fault[i]); + } +} +void Hard_fault_check(void){ + if(*(volatile uint32_t*)HF_FLASH_ADDR == HF_FLAG_VALUE){ + volatile HardFaultLog log; + memcpy(&log,(void*)HF_FLASH_ADDR,sizeof(HardFaultLog)); + #ifdef DEBUG + __asm__ __volatile__("bkpt 1"); + #endif + LED_init(); + while(1){ + LED_Blink(); + } + + } +} +static void EnableGPIOClock(GPIO_TypeDef* port){ + if(port == GPIOA) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA); + else if(port == GPIOB) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB); + else if(port == GPIOC) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOC); + else if(port == GPIOD) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOD); + else if(port == GPIOE) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOE); + else if(port == GPIOF) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOF); + else if(port == GPIOG) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOG); + else if(port == GPIOJ) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOJ); + else if(port == GPIOK) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOK); +} +static void InitGPIO_Output(GPIO_TypeDef* port,uint16_t pin){ + LL_GPIO_SetPinMode(port, pin, LL_GPIO_MODE_OUTPUT); + LL_GPIO_SetPinOutputType(port, pin, LL_GPIO_OUTPUT_PUSHPULL); + LL_GPIO_SetPinSpeed(port, pin, LL_GPIO_SPEED_FREQ_LOW); + LL_GPIO_SetPinPull(port, pin, LL_GPIO_PULL_NO); +} +