Добавлен вывод стека при HardFault
This commit is contained in:
commit
296f25f89b
|
|
@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"cmake": {
|
||||||
|
"inc_dirs": [
|
||||||
|
"./"
|
||||||
|
],
|
||||||
|
"srcs": [
|
||||||
|
"./**.c",
|
||||||
|
"./**.s"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue