Добавлены HardReset в модули Overflow и Assert
This commit is contained in:
parent
f65702e5da
commit
28d9fb8a36
|
|
@ -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
|
||||
|
|
|
|||
11
APP/main.c
11
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue