// // Created by cfif on 31.08.2026. // /* #include #include #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) { // Основной цикл } } */