Skip to content
2 changes: 2 additions & 0 deletions Inc/HALAL/HALAL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
56 changes: 56 additions & 0 deletions Inc/HALAL/HardFault/HardfaultTrace.h
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions STM32H723ZGTX_FLASH.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -82,6 +83,8 @@ SECTIONS
.text :
{
. = ALIGN(4);
_stext = .;

*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
Expand All @@ -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 = .;
Expand Down Expand Up @@ -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);
Expand All @@ -192,6 +210,7 @@ SECTIONS
KEEP(*(.metadata_pool))
. += 0x100;
} >FLASH

/* Uninitialized data section */
. = ALIGN(4);
.bss (NOLOAD) :
Expand Down
69 changes: 69 additions & 0 deletions Src/HALAL/HardFault/HardfaultTrace.c
Original file line number Diff line number Diff line change
@@ -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);
}