Добавлены HardReset в модули Overflow и Assert

This commit is contained in:
cfif 2026-09-29 11:29:40 +03:00
parent f65702e5da
commit 28d9fb8a36
7 changed files with 85 additions and 35 deletions

View File

@ -161,7 +161,19 @@ header file. */
/* USER CODE BEGIN 1 */
//#define configASSERT(x) if ((x) == 0) {nvic_system_reset();}
#define configASSERT(x) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
//#define configASSERT(x) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
#include "HardFault.h"
#define configASSERT(x) \
if ((x) == 0) { \
taskDISABLE_INTERRUPTS(); \
uint32_t sp; \
__asm volatile ("MRS %0, MSP" : "=r"(sp)); \
HardReset_C_Handler((uint32_t *)sp, 0, HARD_RESET_FREERTOS_ASSERT); \
for( ;; ); /* на случай, если NVIC_SystemReset отключён для отладки */ \
}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS

View File

@ -6,6 +6,7 @@
#include "MainModesArbiter.h"
#include "LoggerInterface.h"
#include "PeripheralInterfaces.h"
#include "HardFault.h"
//#define BOOT_AREA_LENGTH (256 * 1024)
//#define FIRMWARE_MAIN_ADDR (0x01000000 + BOOT_AREA_LENGTH)
@ -60,7 +61,17 @@ _Noreturn void stop() {
#if (configCHECK_FOR_STACK_OVERFLOW > 0)
__attribute__((noreturn)) static void trigger_overflow_reset(void) {
uint32_t sp;
__asm volatile ("MRS %0, MSP" : "=r"(sp));
HardReset_C_Handler((uint32_t *)sp, 0 /* MSP */, HARD_RESET_STACK_OVERFLOW);
__builtin_unreachable();
}
void vApplicationStackOverflowHook(TaskHandle_t xTask, const char *pcTaskName) {
trigger_overflow_reset();
PROCESS_UNUSED_VAR(xTask);
PROCESS_UNUSED_VAR(pcTaskName);
STOP

View File

@ -23,7 +23,21 @@
#ifdef NDEBUG
#define DEV_ASSERT(x) ((void)0)
#else
#define DEV_ASSERT(x) do{}while((x) != 1)
// #define DEV_ASSERT(x) do{}while((x) != 1)
#include "FreeRTOS.h"
#include "task.h"
#include "HardFault.h"
#define DEV_ASSERT(x) \
do { \
if ((x) != 1) { \
taskDISABLE_INTERRUPTS(); \
uint32_t sp; \
__asm volatile ("MRS %0, MSP" : "=r"(sp)); \
HardReset_C_Handler((uint32_t *)sp, 0, HARD_RESET_API_ASSERT);\
for( ;; ); \
} \
} while (0)
#endif
#ifndef __IO

View File

@ -106,13 +106,13 @@ static void Mma_InitSubSystems(tMma *env) {
firmwareMetaMap_Main->internal_SW_Version.MDB.revision);
if (hardFault_magic == 0xDEADBEEF) {
hardFault_magic = 0;
if (hardReset_magic == 0xDEADBEEF) {
hardReset_magic = 0;
LoggerFormatError(LOGGER, LOG_INFO_TASK_MAIN, "HardFault addresses (%d):", hardFault_count);
LoggerFormatError(LOGGER, LOG_INFO_TASK_MAIN, "HardReset %d (%d):", hardReset_type, hardReset_count);
for (uint32 i = 0; i < hardFault_count; ++i) {
LoggerFormatError(LOGGER, LOG_INFO_TASK_MAIN, " [%d] 0x%08X", i, hardFault_addresses[i]);
for (uint32 i = 0; i < hardReset_count; ++i) {
LoggerFormatError(LOGGER, LOG_INFO_TASK_MAIN, " [%d] 0x%08X", i, hardReset_addresses[i]);
}
}

View File

@ -13,18 +13,19 @@ extern uint32_t __StackTop;
#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;
__attribute__((section(".save_data"))) volatile uint32_t hardReset_addresses[SIZE_BUF_HARD_FAULT]; // массив для адресов возврата (достаточно 32)
__attribute__((section(".save_data"))) volatile uint32_t hardReset_count;
__attribute__((section(".save_data"))) volatile uint32_t hardReset_type;
__attribute__((section(".save_data"))) volatile uint32_t hardReset_magic;
__attribute__((section(".save_data"))) volatile uint32_t none_data;
void vTaskGetCurrentTaskStackInfo(void **ppvStackStart, void **ppvStackEnd);
void HardFault_C_Handler(uint32_t *sp, uint32_t stack_flag) {
void HardReset_C_Handler(uint32_t *sp, uint32_t stack_flag, eHardResetType typeReset) {
uint32_t *src = sp;
const uint32_t max_ret = sizeof(hardFault_addresses) / sizeof(uint32_t) - 1;
const uint32_t max_ret = sizeof(hardReset_addresses) / sizeof(uint32_t) - 1;
uint32_t *stack_end = NULL;
if (stack_flag == 0) { // Использовался MSP – стек ядра
@ -37,18 +38,19 @@ void HardFault_C_Handler(uint32_t *sp, uint32_t stack_flag) {
stack_end = (uint32_t *) pvStackEnd;
}
hardFault_count = 0;
hardReset_count = 0;
while (src < stack_end && hardFault_count < max_ret) {
while (src < stack_end && hardReset_count < max_ret) {
uint32_t val = *src;
// Проверяем, принадлежит ли значение области кода
if (val >= CODE_START && val < CODE_END) {
hardFault_addresses[hardFault_count++] = val & ~1; // убираем Thumb-бит
hardReset_addresses[hardReset_count++] = val & ~1; // убираем Thumb-бит
}
src++;
}
hardFault_magic = 0xDEADBEEF;
hardReset_type = typeReset;
hardReset_magic = 0xDEADBEEF;
NVIC_SystemReset();

View File

@ -7,10 +7,20 @@
#include "stdint.h"
typedef enum {
HARD_RESET_HARD_FAULT = 0x1,
HARD_RESET_STACK_OVERFLOW = 0x2,
HARD_RESET_FREERTOS_ASSERT = 0x3,
HARD_RESET_API_ASSERT = 0x4
} eHardResetType;
extern void HardReset_C_Handler(uint32_t *sp, uint32_t stack_flag, eHardResetType typeReset);
#define SIZE_BUF_HARD_FAULT 32
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_addresses[32];
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_count;
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
extern __attribute__((section(".save_data"))) volatile uint32_t hardReset_addresses[32];
extern __attribute__((section(".save_data"))) volatile uint32_t hardReset_count;
extern __attribute__((section(".save_data"))) volatile uint32_t hardReset_type;
extern __attribute__((section(".save_data"))) volatile uint32_t hardReset_magic;
#endif //HVAC_M7_HARDFAULT_H

View File

@ -1,21 +1,22 @@
.syntax unified
.thumb
.section .text
.global HardFault_Handler
.type HardFault_Handler, %function
/* ======================= HARD FAULT ======================= */
.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
BNE Fault_UsePSP
Fault_UseMSP:
MRS R0, MSP
MOVS R1, #0
B Fault_CallHandler
Fault_UsePSP:
MRS R0, PSP
MOVS R1, #1
Fault_CallHandler:
MOVS R2, #1 // HARD_RESET_HARD_FAULT
LDR R3, =HardReset_C_Handler
BX R3
.size HardFault_Handler, . - HardFault_Handler