54 lines
1.9 KiB
C
54 lines
1.9 KiB
C
//
|
||
// Created by cfif on 14.07.2026.
|
||
//
|
||
#include "HardFault.h"
|
||
#include CMSIS_device_header
|
||
#include "cmsis_os2.h"
|
||
#include "InternalFlashPage.h"
|
||
|
||
extern uint32_t __StackTop;
|
||
|
||
#define START_FLASH_ADR 0x04001000
|
||
|
||
#define CODE_START (0x01000000 + 64 * 1024)
|
||
#define CODE_END (CODE_START + 704 * 1024) // или используйте символ из линкера
|
||
|
||
__attribute__((section(".save_data"))) volatile uint32_t hardFault_addresses[SIZE_BUF_HARD_FAULT]; // массив для адресов возврата (достаточно 32)
|
||
__attribute__((section(".save_data"))) volatile uint32_t hardFault_count;
|
||
__attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
|
||
|
||
void vTaskGetCurrentTaskStackInfo(void **ppvStackStart, void **ppvStackEnd);
|
||
|
||
void HardFault_C_Handler(uint32_t *sp, uint32_t stack_flag) {
|
||
|
||
uint32_t *src = sp;
|
||
|
||
const uint32_t max_ret = sizeof(hardFault_addresses) / sizeof(uint32_t) - 1;
|
||
uint32_t *stack_end = NULL;
|
||
|
||
if (stack_flag == 0) { // Использовался MSP – стек ядра
|
||
//src += 8; // пропускаем контекст
|
||
stack_end = &__StackTop;
|
||
} else { // Использовался PSP – стек задачи
|
||
void *pvStackStart, *pvStackEnd;
|
||
vTaskGetCurrentTaskStackInfo(&pvStackStart, &pvStackEnd);
|
||
// uint32_t *stack_start = (uint32_t *) pvStackStart;
|
||
stack_end = (uint32_t *) pvStackEnd;
|
||
}
|
||
|
||
hardFault_count = 0;
|
||
|
||
while (src < stack_end && hardFault_count < max_ret) {
|
||
uint32_t val = *src;
|
||
// Проверяем, принадлежит ли значение области кода
|
||
if (val >= CODE_START && val < CODE_END) {
|
||
hardFault_addresses[hardFault_count++] = val & ~1; // убираем Thumb-бит
|
||
}
|
||
src++;
|
||
}
|
||
|
||
hardFault_magic = 0xDEADBEEF;
|
||
|
||
NVIC_SystemReset();
|
||
|
||
} |