HVAC_M7_MONO/MODULES/HVAC_M7_DebugTesting/CheckReset.c

939 lines
36 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by cfif on 31.08.2026.
//
/*
#include <stdint.h>
#include <stdbool.h>
#include "MainModesArbiter_Private.h"
#include "core_cm7_regs.h"
#include "fc7240_rgm_regs.h" // Заголовочный файл RGM
#define LOGGER &env->slog.logger
const char LOG_TASK_MAIN[] = "Init";
// Макрос для проверки активности отладчика
#define CHECK_JTAG_DEBUG_ACTIVE ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
// Источники сброса для Cortex-M7
typedef enum {
RESET_SOURCE_UNKNOWN = 0,
RESET_SOURCE_POWER_ON, // Сброс при включении питания (POR)
RESET_SOURCE_EXTERNAL, // Сброс по внешнему сигналу (NRST)
RESET_SOURCE_WATCHDOG, // Сброс от сторожевого таймера
RESET_SOURCE_SOFTWARE, // Сброс по команде NVIC_SystemReset()
RESET_SOURCE_LOCKUP, // Сброс из-за блокировки ядра (Lockup)
RESET_SOURCE_DEBUG, // Сброс отладчиком
RESET_SOURCE_BROWNOUT, // Сброс при падении напряжения (LVR)
RESET_SOURCE_OPTION_BYTE, // Сброс из-за изменения option bytes
RESET_SOURCE_FIREWALL, // Сброс от Firewall
RESET_SOURCE_MPU, // Сброс из-за нарушения MPU
RESET_SOURCE_BUS_FAULT, // Сброс из-за Bus Fault
RESET_SOURCE_USAGE_FAULT, // Сброс из-за Usage Fault
RESET_SOURCE_MEM_FAULT, // Сброс из-за Memory Management Fault
RESET_SOURCE_CLOCK_ERROR, // Сброс из-за ошибки тактирования
RESET_SOURCE_WAKEUP, // Сброс при пробуждении
RESET_SOURCE_HSM_WATCHDOG, // Сброс от HSM watchdog
} ResetSource_t;
static inline bool IsDebuggerConnected(void)
{
return CHECK_JTAG_DEBUG_ACTIVE;
}
static inline bool IsHardFaultOccurred(void)
{
// Проверяем наличие Hard Fault в регистре HFSR
return (SCB->HFSR & (SCB_HFSR_DEBUGEVT_Msk |
SCB_HFSR_FORCED_Msk |
SCB_HFSR_VECTTBL_Msk)) != 0;
}
static inline bool IsLockupOccurred(void)
{
// Проверяем бит S_LOCKUP в DHCSR
return (CoreDebug->DHCSR & CoreDebug_DHCSR_S_LOCKUP_Msk) != 0;
}
static bool CheckFaultStatus(const char **fault_type)
{
// Проверяем CFSR (Configurable Fault Status Register)
uint32_t cfsr = SCB->CFSR;
if (cfsr & SCB_CFSR_MEMFAULTSR_Msk) {
*fault_type = "Memory Management Fault";
return true;
}
if (cfsr & SCB_CFSR_BUSFAULTSR_Msk) {
*fault_type = "Bus Fault";
return true;
}
if (cfsr & SCB_CFSR_USGFAULTSR_Msk) {
*fault_type = "Usage Fault";
return true;
}
return false;
}
ResetSource_t GetResetSource(void)
{
// ========================================
// 1. Проверяем CoreDebug->DHCSR
// ========================================
uint32_t dhcsr = CoreDebug->DHCSR;
// Сброс отладчиком (бит S_RESET_ST)
if (dhcsr & CoreDebug_DHCSR_S_RESET_ST_Msk) {
return RESET_SOURCE_DEBUG;
}
// Lockup (зависание ядра) - бит S_LOCKUP
if (dhcsr & CoreDebug_DHCSR_S_LOCKUP_Msk) {
return RESET_SOURCE_LOCKUP;
}
// Состояние HALT (остановка ядра отладчиком)
if (dhcsr & CoreDebug_DHCSR_S_HALT_Msk) {
return RESET_SOURCE_DEBUG;
}
// ========================================
// 2. Проверяем SCB (System Control Block)
// ========================================
// Hard Fault (SCB->HFSR)
if (SCB->HFSR & SCB_HFSR_FORCED_Msk) {
// Определяем конкретный тип fault'а через SCB->CFSR
if (SCB->CFSR & SCB_CFSR_MEMFAULTSR_Msk) {
return RESET_SOURCE_MEM_FAULT;
}
if (SCB->CFSR & SCB_CFSR_BUSFAULTSR_Msk) {
return RESET_SOURCE_BUS_FAULT;
}
if (SCB->CFSR & SCB_CFSR_USGFAULTSR_Msk) {
return RESET_SOURCE_USAGE_FAULT;
}
return RESET_SOURCE_LOCKUP;
}
// Ошибка вектора таблицы (VECTTBL)
if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk) {
return RESET_SOURCE_LOCKUP;
}
// Debug Fault (SCB->DFSR)
if (SCB->DFSR & (SCB_DFSR_EXTERNAL_Msk |
SCB_DFSR_VCATCH_Msk |
SCB_DFSR_DWTTRAP_Msk |
SCB_DFSR_BKPT_Msk |
SCB_DFSR_HALTED_Msk)) {
return RESET_SOURCE_DEBUG;
}
// ========================================
// 3. Проверяем CoreDebug->DEMCR
// ========================================
// Векторный catch для различных ошибок
if (CoreDebug->DEMCR & (CoreDebug_DEMCR_VC_HARDERR_Msk |
CoreDebug_DEMCR_VC_INTERR_Msk |
CoreDebug_DEMCR_VC_BUSERR_Msk |
CoreDebug_DEMCR_VC_STATERR_Msk |
CoreDebug_DEMCR_VC_CHKERR_Msk |
CoreDebug_DEMCR_VC_NOCPERR_Msk |
CoreDebug_DEMCR_VC_MMERR_Msk |
CoreDebug_DEMCR_VC_CORERESET_Msk)) {
return RESET_SOURCE_DEBUG;
}
// ========================================
// 4. Проверяем RGM->SRS (System Reset Status)
// ========================================
uint32_t srs = RGM->SRS;
// Power-on reset
if (srs & RGM_SRS_POR_MASK) {
return RESET_SOURCE_POWER_ON;
}
// External pin reset (NRST)
if (srs & RGM_SRS_PIN_MASK) {
return RESET_SOURCE_EXTERNAL;
}
// Watchdog 1 reset
if (srs & RGM_SRS_WDOG1_MASK) {
return RESET_SOURCE_WATCHDOG;
}
// HSM Watchdog reset
if (srs & RGM_SRS_HSM_WDOG_MASK) {
return RESET_SOURCE_HSM_WATCHDOG;
}
// JTAG reset
if (srs & RGM_SRS_JTAG_MASK) {
return RESET_SOURCE_DEBUG;
}
// Low Voltage Reset (Brown-out)
if (srs & RGM_SRS_LVR_MASK) {
return RESET_SOURCE_BROWNOUT;
}
// Clock error reset
if (srs & (RGM_SRS_CLKERR0_MASK | RGM_SRS_CLKERR1_MASK)) {
return RESET_SOURCE_CLOCK_ERROR;
}
// Wakeup reset
if (srs & RGM_SRS_WAKEUP_MASK) {
return RESET_SOURCE_WAKEUP;
}
// System AP reset
if (srs & RGM_SRS_SYSAP_MASK) {
return RESET_SOURCE_SOFTWARE;
}
// System ACK error
if (srs & RGM_SRS_SACKERR_MASK) {
return RESET_SOURCE_LOCKUP;
}
// CMU reset
if (srs & RGM_SRS_CMU_MASK) {
return RESET_SOURCE_CLOCK_ERROR;
}
// LBIST reset
if (srs & RGM_SRS_LBIST_MASK) {
return RESET_SOURCE_POWER_ON;
}
// ========================================
// 5. Проверяем RGM->C0_SRS (CPU0 Reset Status)
// ========================================
uint32_t c0_srs = RGM->C0_SRS;
// CPU software reset
if (c0_srs & RGM_C0_SRS_C0_SWRST_MASK) {
return RESET_SOURCE_SOFTWARE;
}
// CPU watchdog reset
if (c0_srs & RGM_C0_SRS_C0_WDOG_MASK) {
return RESET_SOURCE_WATCHDOG;
}
// CPU Lockup
if (c0_srs & RGM_C0_SRS_C0_LOCKUP_MASK) {
return RESET_SOURCE_LOCKUP;
}
// CPU System Reset
if (c0_srs & RGM_C0_SRS_C0_SYSRST_MASK) {
return RESET_SOURCE_SOFTWARE;
}
// CPU Interrupt reset
if (c0_srs & RGM_C0_SRS_C0_INTM_MASK) {
return RESET_SOURCE_LOCKUP;
}
// ========================================
// 6. Проверяем наличие отладчика
// ========================================
if (dhcsr & CoreDebug_DHCSR_C_DEBUGEN_Msk) {
// Отладчик подключен, но другие признаки не обнаружены
if (dhcsr & (CoreDebug_DHCSR_C_HALT_Msk |
CoreDebug_DHCSR_C_STEP_Msk)) {
return RESET_SOURCE_DEBUG;
}
}
return RESET_SOURCE_UNKNOWN;
}
static const char* GetResetSourceString(ResetSource_t source)
{
switch (source) {
case RESET_SOURCE_UNKNOWN: return "Unknown reset source";
case RESET_SOURCE_POWER_ON: return "Power-on reset (POR)";
case RESET_SOURCE_EXTERNAL: return "External reset (NRST pin)";
case RESET_SOURCE_WATCHDOG: return "Watchdog reset (IWDG/WWDG)";
case RESET_SOURCE_SOFTWARE: return "Software reset (NVIC_SystemReset)";
case RESET_SOURCE_LOCKUP: return "Core Lockup reset";
case RESET_SOURCE_DEBUG: return "Debugger reset";
case RESET_SOURCE_BROWNOUT: return "Low Voltage reset (LVR)";
case RESET_SOURCE_OPTION_BYTE: return "Option byte reset";
case RESET_SOURCE_FIREWALL: return "Firewall reset";
case RESET_SOURCE_MPU: return "MPU violation reset";
case RESET_SOURCE_BUS_FAULT: return "Bus Fault reset";
case RESET_SOURCE_USAGE_FAULT: return "Usage Fault reset";
case RESET_SOURCE_MEM_FAULT: return "Memory Management Fault reset";
case RESET_SOURCE_CLOCK_ERROR: return "Clock error reset";
case RESET_SOURCE_WAKEUP: return "Wakeup reset";
case RESET_SOURCE_HSM_WATCHDOG: return "HSM Watchdog reset";
default: return "Unknown reset source";
}
}
void PrintResetSource(tMma *env)
{
// Проверяем режим отладки
if (CHECK_JTAG_DEBUG_ACTIVE) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Debug mode")
} else {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Run mode")
}
// Получаем источник сброса
ResetSource_t source = GetResetSource();
// Выводим сообщение в зависимости от типа сброса
switch (source) {
case RESET_SOURCE_POWER_ON:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Power-on reset (POR)")
break;
case RESET_SOURCE_EXTERNAL:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: External reset (NRST pin)")
break;
case RESET_SOURCE_WATCHDOG:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Watchdog reset (IWDG/WWDG)")
break;
case RESET_SOURCE_SOFTWARE:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Software reset (NVIC_SystemReset)")
break;
case RESET_SOURCE_LOCKUP:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Core Lockup reset")
break;
case RESET_SOURCE_DEBUG:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Debugger reset")
break;
case RESET_SOURCE_BROWNOUT:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Low Voltage reset (LVR)")
break;
case RESET_SOURCE_OPTION_BYTE:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Option byte reset")
break;
case RESET_SOURCE_FIREWALL:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Firewall reset")
break;
case RESET_SOURCE_MPU:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: MPU violation reset")
break;
case RESET_SOURCE_BUS_FAULT:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Bus Fault reset")
break;
case RESET_SOURCE_USAGE_FAULT:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Usage Fault reset")
break;
case RESET_SOURCE_MEM_FAULT:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Memory Management Fault reset")
break;
case RESET_SOURCE_CLOCK_ERROR:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Clock error reset")
break;
case RESET_SOURCE_WAKEUP:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Wakeup reset")
break;
case RESET_SOURCE_HSM_WATCHDOG:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: HSM Watchdog reset")
break;
default:
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Reset source: Unknown")
break;
}
}
void PrintResetDiagnostics(tMma *env)
{
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "=== Reset Diagnostics ===");
// ========================================
// 1. CoreDebug->DHCSR (Debug Halting Control and Status Register)
// ========================================
uint32_t dhcsr = CoreDebug->DHCSR;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "DHCSR: 0x%08X", dhcsr);
if (dhcsr & CoreDebug_DHCSR_S_RESET_ST_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " S_RESET_ST: System reset occurred");
}
if (dhcsr & CoreDebug_DHCSR_S_RETIRE_ST_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " S_RETIRE_ST: Retired instruction flag");
}
if (dhcsr & CoreDebug_DHCSR_S_LOCKUP_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " S_LOCKUP: Core Lockup detected");
}
if (dhcsr & CoreDebug_DHCSR_S_SLEEP_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " S_SLEEP: Core in sleep mode");
}
if (dhcsr & CoreDebug_DHCSR_S_HALT_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " S_HALT: Core halted (debugger)");
}
if (dhcsr & CoreDebug_DHCSR_S_REGRDY_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " S_REGRDY: Register read/write ready");
}
if (dhcsr & CoreDebug_DHCSR_C_SNAPSTALL_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C_SNAPSTALL: Snap stall enabled");
}
if (dhcsr & CoreDebug_DHCSR_C_MASKINTS_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C_MASKINTS: Interrupts masked");
}
if (dhcsr & CoreDebug_DHCSR_C_STEP_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C_STEP: Single step mode");
}
if (dhcsr & CoreDebug_DHCSR_C_HALT_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C_HALT: Halt request");
}
if (dhcsr & CoreDebug_DHCSR_C_DEBUGEN_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C_DEBUGEN: Debug enabled");
}
// ========================================
// 2. CoreDebug->DEMCR (Debug Exception and Monitor Control Register)
// ========================================
uint32_t demcr = CoreDebug->DEMCR;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "DEMCR: 0x%08X", demcr);
if (demcr & CoreDebug_DEMCR_TRCENA_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " TRCENA: Trace enabled");
}
if (demcr & CoreDebug_DEMCR_MON_REQ_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MON_REQ: Monitor request");
}
if (demcr & CoreDebug_DEMCR_MON_STEP_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MON_STEP: Monitor step");
}
if (demcr & CoreDebug_DEMCR_MON_PEND_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MON_PEND: Monitor pending");
}
if (demcr & CoreDebug_DEMCR_MON_EN_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MON_EN: Monitor enabled");
}
if (demcr & CoreDebug_DEMCR_VC_HARDERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VC_HARDERR: Vector catch Hard Fault");
}
if (demcr & CoreDebug_DEMCR_VC_INTERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VC_INTERR: Vector catch Interrupt error");
}
if (demcr & CoreDebug_DEMCR_VC_BUSERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VC_BUSERR: Vector catch Bus error");
}
if (demcr & CoreDebug_DEMCR_VC_STATERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VC_STATERR: Vector catch State error");
}
if (demcr & CoreDebug_DEMCR_VC_CHKERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VC_CHKERR: Vector catch Check error");
}
if (demcr & CoreDebug_DEMCR_VC_NOCPERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VC_NOCPERR: Vector catch No Coprocessor");
}
if (demcr & CoreDebug_DEMCR_VC_MMERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VC_MMERR: Vector catch Memory Management");
}
if (demcr & CoreDebug_DEMCR_VC_CORERESET_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VC_CORERESET: Vector catch Core reset");
}
// ========================================
// 3. SCB->HFSR (Hard Fault Status Register)
// ========================================
uint32_t hfsr = SCB->HFSR;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "HFSR: 0x%08X", hfsr);
if (hfsr & SCB_HFSR_DEBUGEVT_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " DEBUGEVT: Debug event");
}
if (hfsr & SCB_HFSR_FORCED_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " FORCED: Hard Fault forced");
}
if (hfsr & SCB_HFSR_VECTTBL_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VECTTBL: Vector table read error");
}
// ========================================
// 4. SCB->CFSR (Configurable Fault Status Register)
// ========================================
uint32_t cfsr = SCB->CFSR;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "CFSR: 0x%08X", cfsr);
// Memory Management Fault
if (cfsr & SCB_CFSR_MEMFAULTSR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MEMFAULT: Memory Management Fault");
if (cfsr & SCB_CFSR_IACCVIOL_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " IACCVIOL: Instruction access violation");
}
if (cfsr & SCB_CFSR_DACCVIOL_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " DACCVIOL: Data access violation");
}
if (cfsr & SCB_CFSR_MUNSTKERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MUNSTKERR: Unstacking error");
}
if (cfsr & SCB_CFSR_MSTKERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MSTKERR: Stacking error");
}
if (cfsr & SCB_CFSR_MLSPERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MLSPERR: Lazy state error");
}
if (cfsr & SCB_CFSR_MMARVALID_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " MMARVALID: MMFAR valid");
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, " MMFAR: 0x%08X", SCB->MMFAR);
}
}
// Bus Fault
if (cfsr & SCB_CFSR_BUSFAULTSR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " BUSFAULT: Bus Fault");
if (cfsr & SCB_CFSR_IBUSERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " IBUSERR: Instruction bus error");
}
if (cfsr & SCB_CFSR_PRECISERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " PRECISERR: Precise data bus error");
}
if (cfsr & SCB_CFSR_IMPRECISERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " IMPRECISERR: Imprecise data bus error");
}
if (cfsr & SCB_CFSR_UNSTKERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " UNSTKERR: Unstacking error");
}
if (cfsr & SCB_CFSR_STKERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " STKERR: Stacking error");
}
if (cfsr & SCB_CFSR_LSPERR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " LSPERR: Lazy state error");
}
if (cfsr & SCB_CFSR_BFARVALID_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " BFARVALID: BFAR valid");
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, " BFAR: 0x%08X", SCB->BFAR);
}
}
// Usage Fault
if (cfsr & SCB_CFSR_USGFAULTSR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " USGFAULT: Usage Fault");
if (cfsr & SCB_CFSR_UNDEFINSTR_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " UNDEFINSTR: Undefined instruction");
}
if (cfsr & SCB_CFSR_INVSTATE_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " INVSTATE: Invalid state");
}
if (cfsr & SCB_CFSR_INVPC_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " INVPC: Invalid PC");
}
if (cfsr & SCB_CFSR_NOCP_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " NOCP: No coprocessor");
}
if (cfsr & SCB_CFSR_UNALIGNED_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " UNALIGNED: Unaligned access");
}
if (cfsr & SCB_CFSR_DIVBYZERO_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " DIVBYZERO: Division by zero");
}
}
// ========================================
// 5. SCB->DFSR (Debug Fault Status Register)
// ========================================
uint32_t dfsr = SCB->DFSR;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "DFSR: 0x%08X", dfsr);
if (dfsr & SCB_DFSR_EXTERNAL_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " EXTERNAL: External debug request");
}
if (dfsr & SCB_DFSR_VCATCH_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " VCATCH: Vector catch");
}
if (dfsr & SCB_DFSR_DWTTRAP_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " DWTTRAP: DWT trap");
}
if (dfsr & SCB_DFSR_BKPT_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " BKPT: Breakpoint");
}
if (dfsr & SCB_DFSR_HALTED_Msk) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " HALTED: Core halted");
}
// ========================================
// 6. RGM->SRS (System Reset Status Register)
// ========================================
uint32_t srs = RGM->SRS;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "RGM->SRS: 0x%08X", srs);
if (srs & RGM_SRS_SYSRST_TOUT_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SYSRST_TOUT: System reset timeout");
}
if (srs & RGM_SRS_PINRST_TOUT_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " PINRST_TOUT: Pin reset timeout");
}
if (srs & RGM_SRS_FSM_ERR_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " FSM_ERR: FSM error");
}
if (srs & RGM_SRS_LBIST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " LBIST: LBIST reset");
}
if (srs & RGM_SRS_CMU_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " CMU: CMU reset");
}
if (srs & RGM_SRS_SACKERR_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SACKERR: System ACK error");
}
if (srs & RGM_SRS_WDOG1_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " WDOG1: Watchdog 1 reset");
}
if (srs & RGM_SRS_SYSAP_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SYSAP: System AP reset");
}
if (srs & RGM_SRS_JTAG_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " JTAG: JTAG reset");
}
if (srs & RGM_SRS_POR_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " POR: Power-on reset");
}
if (srs & RGM_SRS_PIN_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " PIN: External pin reset");
}
if (srs & RGM_SRS_HSM_WDOG_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " HSM_WDOG: HSM watchdog reset");
}
if (srs & RGM_SRS_FCSMU_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " FCSMU: FCSMU reset");
}
if (srs & RGM_SRS_CLKERR0_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " CLKERR0: Clock error 0 reset");
}
if (srs & RGM_SRS_CLKERR1_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " CLKERR1: Clock error 1 reset");
}
if (srs & RGM_SRS_LVR_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " LVR: Low Voltage reset");
}
if (srs & RGM_SRS_WAKEUP_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " WAKEUP: Wakeup reset");
}
// ========================================
// 7. RGM->SSRS (Sticky System Reset Status Register)
// ========================================
uint32_t ssrs = RGM->SSRS;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "RGM->SSRS: 0x%08X", ssrs);
if (ssrs & RGM_SSRS_SYSRST_TOUT_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SYSRST_TOUT: System reset timeout (sticky)");
}
if (ssrs & RGM_SSRS_PINRST_TOUT_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " PINRST_TOUT: Pin reset timeout (sticky)");
}
if (ssrs & RGM_SSRS_FSM_ERR_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " FSM_ERR: FSM error (sticky)");
}
if (ssrs & RGM_SSRS_LBIST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " LBIST: LBIST reset (sticky)");
}
if (ssrs & RGM_SSRS_CMU_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " CMU: CMU reset (sticky)");
}
if (ssrs & RGM_SSRS_SACKERR_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SACKERR_ST: System ACK error (sticky)");
}
if (ssrs & RGM_SSRS_WDOG1_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " WDOG1: Watchdog 1 reset (sticky)");
}
if (ssrs & RGM_SSRS_SYSAP_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SYSAP_ST: System AP reset (sticky)");
}
if (ssrs & RGM_SSRS_JTAG_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " JTAG_ST: JTAG reset (sticky)");
}
if (ssrs & RGM_SSRS_POR_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " POR_ST: Power-on reset (sticky)");
}
if (ssrs & RGM_SSRS_PIN_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " PIN_ST: External pin reset (sticky)");
}
if (ssrs & RGM_SSRS_HSMWDOG_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " HSMWDOG_ST: HSM watchdog reset (sticky)");
}
if (ssrs & RGM_SSRS_FCSMU_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " FCSMU_ST: FCSMU reset (sticky)");
}
if (ssrs & RGM_SSRS_CLKERR0_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " CLKERR0_ST: Clock error 0 reset (sticky)");
}
if (ssrs & RGM_SSRS_CLKERR1_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " CLKERR1_ST: Clock error 1 reset (sticky)");
}
if (ssrs & RGM_SSRS_LVR_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " LVR: Low Voltage reset (sticky)");
}
if (ssrs & RGM_SSRS_WAKEUP_ST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " WAKEUP_ST: Wakeup reset (sticky)");
}
// ========================================
// 8. RGM->C0_SRS (CPU0 System Reset Status Register)
// ========================================
uint32_t c0_srs = RGM->C0_SRS;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "RGM->C0_SRS: 0x%08X", c0_srs);
if (c0_srs & RGM_C0_SRS_SYSRST_TOUT_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SYSRST_TOUT: System reset timeout (CPU0)");
}
if (c0_srs & RGM_C0_SRS_PINRST_TOUT_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " PINRST_TOUT: Pin reset timeout (CPU0)");
}
if (c0_srs & RGM_C0_SRS_FSM_ERR_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " FSM_ERR: FSM error (CPU0)");
}
if (c0_srs & RGM_C0_SRS_C0_SWRST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SWRST: CPU0 software reset");
}
if (c0_srs & RGM_C0_SRS_C0_INTM_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_INTM: CPU0 interrupt reset");
}
if (c0_srs & RGM_C0_SRS_C0_WDOG_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_WDOG: CPU0 watchdog reset");
}
if (c0_srs & RGM_C0_SRS_C0_SYSRST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SYSRST: CPU0 system reset");
}
if (c0_srs & RGM_C0_SRS_C0_LOCKUP_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_LOCKUP: CPU0 lockup reset");
}
if (c0_srs & RGM_C0_SRS_C0_SRS_MASK) {
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, " C0_SRS: 0x%04X", (c0_srs & RGM_C0_SRS_C0_SRS_MASK) >> RGM_C0_SRS_C0_SRS_SHIFT);
}
// ========================================
// 9. RGM->C0_SSRS (CPU0 Sticky System Reset Status Register)
// ========================================
uint32_t c0_ssrs = RGM->C0_SSRS;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "RGM->C0_SSRS: 0x%08X", c0_ssrs);
if (c0_ssrs & RGM_C0_SSRS_SYSRST_TOUT_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SYSRST_TOUT: System reset timeout (CPU0 sticky)");
}
if (c0_ssrs & RGM_C0_SSRS_PINRST_TOUT_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " PINRST_TOUT: Pin reset timeout (CPU0 sticky)");
}
if (c0_ssrs & RGM_C0_SSRS_FSM_ERR_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " FSM_ERR: FSM error (CPU0 sticky)");
}
if (c0_ssrs & RGM_C0_SSRS_C0_SWRST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SWRST: CPU0 software reset (sticky)");
}
if (c0_ssrs & RGM_C0_SSRS_C0_INTM_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_INTM: CPU0 interrupt reset (sticky)");
}
if (c0_ssrs & RGM_C0_SSRS_C0_WDOG_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_WDOG: CPU0 watchdog reset (sticky)");
}
if (c0_ssrs & RGM_C0_SSRS_C0_SYSRST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SYSRST: CPU0 system reset (sticky)");
}
if (c0_ssrs & RGM_C0_SSRS_C0_LOCKUP_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_LOCKUP: CPU0 lockup reset (sticky)");
}
if (c0_ssrs & RGM_C0_SSRS_SSRS_MASK) {
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, " SSRS: 0x%04X", (c0_ssrs & RGM_C0_SSRS_SSRS_MASK) >> RGM_C0_SSRS_SSRS_SHIFT);
}
// ========================================
// 10. RGM->C0_CFG (CPU0 Reset Configuration Register)
// ========================================
uint32_t c0_cfg = RGM->C0_CFG;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "RGM->C0_CFG: 0x%08X", c0_cfg);
if (c0_cfg & RGM_C0_CFG_C0_SWRST_EN_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SWRST_EN: Software reset enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_INTM_EN_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_INTM_EN: Interrupt reset enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_WDOG_EN_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_WDOG_EN: Watchdog reset enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_SYSRST_EN_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SYSRST_EN: System reset enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_LOCKUP_EN_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_LOCKUP_EN: Lockup reset enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_SWRST_IE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SWRST_IE: Software reset interrupt enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_INTM_IE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_INTM_IE: Interrupt reset interrupt enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_WDOG_IE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_WDOG_IE: Watchdog interrupt enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_SYSRST_IE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SYSRST_IE: System reset interrupt enabled");
}
if (c0_cfg & RGM_C0_CFG_C0_LOCKUP_IE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_LOCKUP_IE: Lockup interrupt enabled");
}
// ========================================
// 11. RGM->C0_RST (CPU0 Reset Register)
// ========================================
uint32_t c0_rst = RGM->C0_RST;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "RGM->C0_RST: 0x%08X", c0_rst);
if (c0_rst & RGM_C0_RST_C0_OUT_OF_RST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_OUT_OF_RST: CPU0 out of reset");
}
if (c0_rst & RGM_C0_RST_C0_SWRST_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " C0_SWRST: CPU0 software reset request");
}
// ========================================
// 12. RGM->RSTFLT (Reset Filter Control Register)
// ========================================
uint32_t rstflt = RGM->RSTFLT;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "RGM->RSTFLT: 0x%08X", rstflt);
if (rstflt & RGM_RSTFLT_RSTFLT_BUSW_MASK) {
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, " RSTFLT_BUSW: 0x%02X", (rstflt & RGM_RSTFLT_RSTFLT_BUSW_MASK) >> RGM_RSTFLT_RSTFLT_BUSW_SHIFT);
}
if (rstflt & RGM_RSTFLT_RSTFLT_AON_LP_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " RSTFLT_AON_LP: AON low-power filter enabled");
}
if (rstflt & RGM_RSTFLT_RSTFLT_AON_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " RSTFLT_AON: AON filter enabled");
}
if (rstflt & RGM_RSTFLT_RSTFLT_BUS_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " RSTFLT_BUS: Bus filter enabled");
}
// ========================================
// 13. RGM->SRIE (System Reset Interrupt Enable Register)
// ========================================
uint32_t srie = RGM->SRIE;
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, "RGM->SRIE: 0x%08X", srie);
if (srie & RGM_SRIE_SACKERR_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SACKERR_RIE: ACK error interrupt enabled");
}
if (srie & RGM_SRIE_WDOG1_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " WDOG1_RIE: Watchdog 1 interrupt enabled");
}
if (srie & RGM_SRIE_SYSAP_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SYSAP_RIE: System AP interrupt enabled");
}
if (srie & RGM_SRIE_SW_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " SW_RIE: Software interrupt enabled");
}
if (srie & RGM_SRIE_CPULOC_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " CPULOC_RIE: CPU lockup interrupt enabled");
}
if (srie & RGM_SRIE_JTAG_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " JTAG_RIE: JTAG interrupt enabled");
}
if (srie & RGM_SRIE_GLOBAL_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " GLOBAL_RIE: Global interrupt enabled");
}
if (srie & RGM_SRIE_PIN_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " PIN_RIE: Pin reset interrupt enabled");
}
if (srie & RGM_SRIE_WDG_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " WDG_RIE: Watchdog interrupt enabled");
}
if (srie & RGM_SRIE_CLKERR0_RIE_MASK) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, " CLKERR0_RIE: Clock error 0 interrupt enabled");
}
if (srie & RGM_SRIE_DELAY_MASK) {
LoggerFormatInfo(LOGGER, LOG_TASK_MAIN, " DELAY: 0x%02X", (srie & RGM_SRIE_DELAY_MASK) >> RGM_SRIE_DELAY_SHIFT);
}
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "=========================");
}
void ClearResetFlags(void)
{
// Очищаем "липкие" флаги записью 1 в соответствующие биты
// Для очистки нужно записать 1 в биты, которые хотим сбросить
// Очищаем SSRS (Sticky SRS)
RGM->SSRS = RGM_SSRS_MASK;
// Очищаем C0_SSRS (Sticky CPU0 SRS)
RGM->C0_SSRS = RGM_C0_SSRS_MASK;
// Для SRS и C0_SRS - они читаются только для статуса,
// их очистка происходит через SSRS
}
void AnalyzeAndPrintResetReason(tMma *env)
{
// Небольшая задержка для стабилизации
for (volatile int i = 0; i < 1000; i++);
// Выводим режим работы
if (CHECK_JTAG_DEBUG_ACTIVE) {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Debug mode")
} else {
LoggerInfoStatic(LOGGER, LOG_TASK_MAIN, "Run mode")
}
// Анализируем и выводим причину сброса
//PrintResetSource(env);
// Если нужна детальная диагностика - раскомментировать
PrintResetDiagnostics(env);
// Очищаем флаги сброса
ClearResetFlags();
}
// Пример использования в main()
int main(void)
{
tMma *env = GetMmaEnvironment(); // или как у вас создается env
// Инициализация системы
SystemInit();
// Инициализация логгера (должна быть до вызова функции)
LoggerInit();
// Анализ причины перезагрузки
AnalyzeAndPrintResetReason(env);
// Дальнейшая инициализация...
while(1) {
// Основной цикл
}
}
*/