/*---------------------------------------------------------------------------- * Copyright (c) Fenda Technologies Co., Ltd. 2020. All rights reserved. * * Description: watchdog_api.c * * Author: saimen * * Create: 2022-7-16 *--------------------------------------------------------------------------*/ //lib #include #include //os #include "FreeRTOS.h" #include "task.h" //sdk //#include "apollo4b.h"//uninclude am_hal_lib #include "am_mcu_apollo.h" //drv #include "sys_config.h" //#include "sys_restart.h" #include "watchdog_api.h" #include "rtc_api.h" //user #define ENABLE_STATIC_PRINT false extern uint32_t am_util_stdio_printf(const char *pcFmt, ...); #define static_print_remind(...) am_util_stdio_printf(__VA_ARGS__) #if ENABLE_STATIC_PRINT #define static_print_info(...) am_util_stdio_printf(__VA_ARGS__) #else #define static_print_info(...) #endif #define MCU_WDT_RST_TIMES (15) // Note: max value, 16*16 >= 256; #define MCU_WDT_ISR_TIMES (MCU_WDT_RST_TIMES - 2) // seconds static uint32_t g_ui32ResetStatus = 0; am_hal_wdt_config_t g_watchdog_config = { // Set the clock for 16HZ .eClockSource = AM_HAL_WDT_16HZ, // Enable the interrupt, and set it for 3/4 of a second. .bInterruptEnable = true, .ui32InterruptValue = (16 * MCU_WDT_ISR_TIMES), // Enable the reset, and set it for 15 seconds. .bResetEnable = true, .ui32ResetValue = (16 * MCU_WDT_RST_TIMES), // No DSP. .bAlertOnDSPReset = false, }; void am_watchdog_isr(void) { uint32_t ui32Status; #if defined(AM_PART_APOLLO4) // am_hal_wdt_interrupt_status_get(); // am_hal_wdt_interrupt_clear(); am_hal_wdt_interrupt_status_get(AM_HAL_WDT_MCU, &ui32Status, true); am_hal_wdt_interrupt_clear(AM_HAL_WDT_MCU, ui32Status); #else am_hal_wdt_int_clear(); #endif static_print_remind("am_watchdog_isr... \r\n"); /*Note: 不使用正常重启流程保存数据,是因为正常保存流程涉及到文件操作,文件操作需要使用动态内存申请,动态内存申请本身就会引发 堵塞导致看门狗超时,最终导致保存失败; */ #include "log_api.h" uint32_t timestamp = rtc_api_get_utc_timestamp(); log_api_record_error(timestamp, EVT_DRIVE_ERROR, INFO1_MCU, INFO2_MCU_WDT_ISR, 0, NULL); //硬狗超时 #include "sys_restart.h" //sys_anomaly_data_save(); extern uint32_t HardFault_Handler(void); HardFault_Handler(); static_print_remind("wdt data recover end\r\n"); while(1); //等待看门狗重启设备 } void watchdog_api_init(void) { #if 0 #if defined(AM_PART_APOLLO4) am_hal_wdt_start(AM_HAL_WDT_MCU, true); #else // am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_LFRC_START, 0); am_hal_wdt_init(&g_sWatchdogConfig); am_hal_wdt_start(); #endif #if AM_CMSIS_REGS NVIC_EnableIRQ(WDT_IRQn); #else am_hal_interrupt_enable(AM_HAL_INTERRUPT_WATCHDOG); #endif #else am_hal_reset_status_t sStatus; am_hal_reset_status_get(&sStatus); g_ui32ResetStatus = sStatus.eStatus; static_print_remind("Reset Status Register = 0x%x\r\n", g_ui32ResetStatus); am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_LFRC_START, 0); // // Configure the watchdog. // am_hal_wdt_config(AM_HAL_WDT_MCU, &g_watchdog_config); am_hal_wdt_interrupt_enable(AM_HAL_WDT_MCU, AM_HAL_WDT_INTERRUPT_MCU); // // Enable the interrupt for the watchdog in the NVIC. // NVIC_SetPriority(WDT_IRQn, AM_IRQ_PRIORITY_DEFAULT-2); NVIC_EnableIRQ(WDT_IRQn); am_hal_interrupt_master_enable(); // // Enable the watchdog. // am_hal_wdt_start(AM_HAL_WDT_MCU, false); #endif } uint8_t watchdog_api_get_status(void) { #if AM_CMSIS_REGS return WDT->CFG | WDT_CFG_WDTEN_Msk; #else return (AM_REG(WDT, CFG) & AM_REG_WDT_CFG_WDTEN(AM_REG_WDT_CFG_WDTEN_M)); #endif } uint32_t watchdog_api_get_rst_ms(void) { return MCU_WDT_ISR_TIMES*1000; } void watchdog_api_feed(void) { am_hal_wdt_restart(AM_HAL_WDT_MCU); }