Добавлен вывод стека при HardFault

This commit is contained in:
cfif 2026-07-14 17:34:02 +03:00
commit 296f25f89b
4 changed files with 102 additions and 0 deletions

54
HardFault.c Normal file
View File

@ -0,0 +1,54 @@
//
// 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(".ncache_bss"))) volatile uint32_t hardFault_addresses[SIZE_BUF_HARD_FAULT]; // массив для адресов возврата (достаточно 32)
__attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_count;
__attribute__((section(".ncache_bss"))) 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();
}

16
HardFault.h Normal file
View File

@ -0,0 +1,16 @@
//
// Created by cfif on 14.07.2026.
//
#ifndef HVAC_M7_HARDFAULT_H
#define HVAC_M7_HARDFAULT_H
#include "stdint.h"
#define SIZE_BUF_HARD_FAULT 32
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_addresses[32];
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_count;
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_magic;
#endif //HVAC_M7_HARDFAULT_H

21
HardFault.s Normal file
View File

@ -0,0 +1,21 @@
.syntax unified
.thumb
.section .text
.global HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
// Проверяем бит 2 в LR: если 1, то использовался PSP, иначе MSP
TST LR, #4
BNE UsePSP
UseMSP:
MRS R0, MSP // R0 = указатель MSP
MOVS R1, #0 // R1 = флаг 0 (MSP)
B CallHandler
UsePSP:
MRS R0, PSP // R0 = указатель PSP
MOVS R1, #1 // R1 = флаг 1 (PSP)
CallHandler:
LDR R2, =HardFault_C_Handler
BX R2
.size HardFault_Handler, . - HardFault_Handler

11
modular.json Normal file
View File

@ -0,0 +1,11 @@
{
"cmake": {
"inc_dirs": [
"./"
],
"srcs": [
"./**.c",
"./**.s"
]
}
}