From 28d9fb8a36a26d434a0b794181e3e297f31156cf Mon Sep 17 00:00:00 2001 From: cfif Date: Tue, 29 Sep 2026 11:29:40 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20HardReset=20=D0=B2=20=D0=BC=D0=BE=D0=B4=D1=83?= =?UTF-8?q?=D0=BB=D0=B8=20Overflow=20=D0=B8=20Assert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APP/FreeRTOSConfig.h | 14 ++++++++- APP/main.c | 11 +++++++ MODULES/Device_Flagchip_FC7240/typedef.h | 16 +++++++++- .../MainModesArbiter_InitStage.c | 10 +++--- MODULES/HVAC_M7_HardFault/HardFault.c | 22 +++++++------ MODULES/HVAC_M7_HardFault/HardFault.h | 16 ++++++++-- MODULES/HVAC_M7_HardFault/HardFault.s | 31 ++++++++++--------- 7 files changed, 85 insertions(+), 35 deletions(-) diff --git a/APP/FreeRTOSConfig.h b/APP/FreeRTOSConfig.h index 92419f1..f71b139 100644 --- a/APP/FreeRTOSConfig.h +++ b/APP/FreeRTOSConfig.h @@ -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 diff --git a/APP/main.c b/APP/main.c index 53a5aaf..30aa36b 100644 --- a/APP/main.c +++ b/APP/main.c @@ -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 diff --git a/MODULES/Device_Flagchip_FC7240/typedef.h b/MODULES/Device_Flagchip_FC7240/typedef.h index ead96ba..4032d34 100644 --- a/MODULES/Device_Flagchip_FC7240/typedef.h +++ b/MODULES/Device_Flagchip_FC7240/typedef.h @@ -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 diff --git a/MODULES/HVAC_M7_DebugTesting/MainModesArbiter_InitStage.c b/MODULES/HVAC_M7_DebugTesting/MainModesArbiter_InitStage.c index fdbb021..d0b3b18 100644 --- a/MODULES/HVAC_M7_DebugTesting/MainModesArbiter_InitStage.c +++ b/MODULES/HVAC_M7_DebugTesting/MainModesArbiter_InitStage.c @@ -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]); } } diff --git a/MODULES/HVAC_M7_HardFault/HardFault.c b/MODULES/HVAC_M7_HardFault/HardFault.c index 05b38e7..579f483 100644 --- a/MODULES/HVAC_M7_HardFault/HardFault.c +++ b/MODULES/HVAC_M7_HardFault/HardFault.c @@ -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,19 +38,20 @@ 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(); -} \ No newline at end of file +} diff --git a/MODULES/HVAC_M7_HardFault/HardFault.h b/MODULES/HVAC_M7_HardFault/HardFault.h index 320f8c6..6e4c5e7 100644 --- a/MODULES/HVAC_M7_HardFault/HardFault.h +++ b/MODULES/HVAC_M7_HardFault/HardFault.h @@ -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 diff --git a/MODULES/HVAC_M7_HardFault/HardFault.s b/MODULES/HVAC_M7_HardFault/HardFault.s index f1a61a3..08265ec 100644 --- a/MODULES/HVAC_M7_HardFault/HardFault.s +++ b/MODULES/HVAC_M7_HardFault/HardFault.s @@ -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 \ No newline at end of file + 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