Добавлены HardReset в модули Overflow и Assert
This commit is contained in:
parent
f65702e5da
commit
28d9fb8a36
|
|
@ -161,7 +161,19 @@ header file. */
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
//#define configASSERT(x) if ((x) == 0) {nvic_system_reset();}
|
//#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 */
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
/* 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 "MainModesArbiter.h"
|
||||||
#include "LoggerInterface.h"
|
#include "LoggerInterface.h"
|
||||||
#include "PeripheralInterfaces.h"
|
#include "PeripheralInterfaces.h"
|
||||||
|
#include "HardFault.h"
|
||||||
|
|
||||||
//#define BOOT_AREA_LENGTH (256 * 1024)
|
//#define BOOT_AREA_LENGTH (256 * 1024)
|
||||||
//#define FIRMWARE_MAIN_ADDR (0x01000000 + BOOT_AREA_LENGTH)
|
//#define FIRMWARE_MAIN_ADDR (0x01000000 + BOOT_AREA_LENGTH)
|
||||||
|
|
@ -60,7 +61,17 @@ _Noreturn void stop() {
|
||||||
|
|
||||||
#if (configCHECK_FOR_STACK_OVERFLOW > 0)
|
#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) {
|
void vApplicationStackOverflowHook(TaskHandle_t xTask, const char *pcTaskName) {
|
||||||
|
|
||||||
|
trigger_overflow_reset();
|
||||||
|
|
||||||
PROCESS_UNUSED_VAR(xTask);
|
PROCESS_UNUSED_VAR(xTask);
|
||||||
PROCESS_UNUSED_VAR(pcTaskName);
|
PROCESS_UNUSED_VAR(pcTaskName);
|
||||||
STOP
|
STOP
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,21 @@
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define DEV_ASSERT(x) ((void)0)
|
#define DEV_ASSERT(x) ((void)0)
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef __IO
|
#ifndef __IO
|
||||||
|
|
|
||||||
|
|
@ -106,13 +106,13 @@ static void Mma_InitSubSystems(tMma *env) {
|
||||||
firmwareMetaMap_Main->internal_SW_Version.MDB.revision);
|
firmwareMetaMap_Main->internal_SW_Version.MDB.revision);
|
||||||
|
|
||||||
|
|
||||||
if (hardFault_magic == 0xDEADBEEF) {
|
if (hardReset_magic == 0xDEADBEEF) {
|
||||||
hardFault_magic = 0;
|
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) {
|
for (uint32 i = 0; i < hardReset_count; ++i) {
|
||||||
LoggerFormatError(LOGGER, LOG_INFO_TASK_MAIN, " [%d] 0x%08X", i, hardFault_addresses[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_START (0x01000000 + 64 * 1024)
|
||||||
#define CODE_END (CODE_START + 704 * 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 hardReset_addresses[SIZE_BUF_HARD_FAULT]; // массив для адресов возврата (достаточно 32)
|
||||||
__attribute__((section(".save_data"))) volatile uint32_t hardFault_count;
|
__attribute__((section(".save_data"))) volatile uint32_t hardReset_count;
|
||||||
__attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
|
__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;
|
__attribute__((section(".save_data"))) volatile uint32_t none_data;
|
||||||
|
|
||||||
void vTaskGetCurrentTaskStackInfo(void **ppvStackStart, void **ppvStackEnd);
|
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;
|
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;
|
uint32_t *stack_end = NULL;
|
||||||
|
|
||||||
if (stack_flag == 0) { // Использовался MSP – стек ядра
|
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;
|
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;
|
uint32_t val = *src;
|
||||||
// Проверяем, принадлежит ли значение области кода
|
// Проверяем, принадлежит ли значение области кода
|
||||||
if (val >= CODE_START && val < CODE_END) {
|
if (val >= CODE_START && val < CODE_END) {
|
||||||
hardFault_addresses[hardFault_count++] = val & ~1; // убираем Thumb-бит
|
hardReset_addresses[hardReset_count++] = val & ~1; // убираем Thumb-бит
|
||||||
}
|
}
|
||||||
src++;
|
src++;
|
||||||
}
|
}
|
||||||
|
|
||||||
hardFault_magic = 0xDEADBEEF;
|
hardReset_type = typeReset;
|
||||||
|
hardReset_magic = 0xDEADBEEF;
|
||||||
|
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,20 @@
|
||||||
|
|
||||||
#include "stdint.h"
|
#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
|
#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 hardReset_addresses[32];
|
||||||
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_count;
|
extern __attribute__((section(".save_data"))) volatile uint32_t hardReset_count;
|
||||||
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
|
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
|
#endif //HVAC_M7_HARDFAULT_H
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,22 @@
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
.section .text
|
.section .text
|
||||||
|
|
||||||
|
/* ======================= HARD FAULT ======================= */
|
||||||
.global HardFault_Handler
|
.global HardFault_Handler
|
||||||
.type HardFault_Handler, %function
|
.type HardFault_Handler, %function
|
||||||
|
|
||||||
HardFault_Handler:
|
HardFault_Handler:
|
||||||
// Проверяем бит 2 в LR: если 1, то использовался PSP, иначе MSP
|
|
||||||
TST LR, #4
|
TST LR, #4
|
||||||
BNE UsePSP
|
BNE Fault_UsePSP
|
||||||
UseMSP:
|
Fault_UseMSP:
|
||||||
MRS R0, MSP // R0 = указатель MSP
|
MRS R0, MSP
|
||||||
MOVS R1, #0 // R1 = флаг 0 (MSP)
|
MOVS R1, #0
|
||||||
B CallHandler
|
B Fault_CallHandler
|
||||||
UsePSP:
|
Fault_UsePSP:
|
||||||
MRS R0, PSP // R0 = указатель PSP
|
MRS R0, PSP
|
||||||
MOVS R1, #1 // R1 = флаг 1 (PSP)
|
MOVS R1, #1
|
||||||
CallHandler:
|
Fault_CallHandler:
|
||||||
LDR R2, =HardFault_C_Handler
|
MOVS R2, #1 // HARD_RESET_HARD_FAULT
|
||||||
BX R2
|
LDR R3, =HardReset_C_Handler
|
||||||
|
BX R3
|
||||||
.size HardFault_Handler, . - HardFault_Handler
|
.size HardFault_Handler, . - HardFault_Handler
|
||||||
Loading…
Reference in New Issue