155 lines
4.1 KiB
C
155 lines
4.1 KiB
C
/*----------------------------------------------------------------------------
|
|
* Copyright (c) Fenda Technologies Co., Ltd. 2020. All rights reserved.
|
|
*
|
|
* Description: watchdog_api.c
|
|
*
|
|
* Author: saimen
|
|
*
|
|
* Create: 2022-7-16
|
|
*--------------------------------------------------------------------------*/
|
|
//lib
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
//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);
|
|
}
|