一:简介
看门狗(Watchdog)是一种计算机硬件或软件的监控机制,主要作用是监测系统的运行状态,并在系统出现异常或故障时采取相应措施,以保证系统的稳定性和可靠性。
具体来说,看门狗的工作原理是,在系统运行以后启动看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。硬件看门狗是利用定时器来监控主程序的运行,在主程序的运行过程中,要在定时时间到之前对定时器进行复位,如果出现死循环,或者说PC指针不能回来,这时看门狗就会介入,采取相应的措施保证系统的稳定性和可靠性。
以下介绍的是GD32F4的独立看门狗定时器的使用:
一:库函数接口
1.看门狗读写保护
/* enable write access to FWDGT_PSC and FWDGT_RLD */
void fwdgt_write_enable(void);
/* disable write access to FWDGT_PSC and FWDGT_RLD */
void fwdgt_write_disable(void);
2.看门狗使能
/* start the free watchdog timer counter */
void fwdgt_enable(void);
3.独立看么狗参数配置
1)时钟预分频
/* configure the free watchdog timer counter prescaler value */
ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value);
2)重装值设置
/* configure the free watchdog timer counter reload value */
ErrStatus fwdgt_reload_value_config(uint16_t reload_value);
等效总接口:
/* configure counter reload value, and prescaler divider value */
ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div);
4.喂狗,重装看门狗定时器
/* get flag state of FWDGT */
FlagStatus fwdgt_flag_get(uint16_t flag);
5.标志位查询
/* get flag state of FWDGT */
FlagStatus fwdgt_flag_get(uint16_t flag);
二:应用示例
1.初始化
void model_fwdgt_Init(void (*callback_function)(void))
{
uint16_t timeout_t=0xFFFFU;
/* enable IRC32K */
rcu_osci_on(RCU_IRC32K);
/* wait till IRC32K is ready */
while(SUCCESS != rcu_osci_stab_wait(RCU_IRC32K))
{
if(timeout_t > 0)
{
timeout_t--;
}
else
{
callback_function();
break;
}
}
/* confiure FWDGT counter clock: 32KHz(IRC32K) / 64 = 0.5 KHz */
fwdgt_config(500,FWDGT_PSC_DIV64);
fwdgt_write_disable();
/* After 1S to generate a reset */
fwdgt_enable();
}
2.重装喂狗函数
void model_fwdgt_reload(void)
{
/* uncock fwdgt write protect*/
fwdgt_write_enable();
/* feed fwdgt */
fwdgt_counter_reload();
}
3.人为溢出
/* 某种条件触发 */
if(something)
{
/* 重新配置看门狗计数值 */
fwdgt_write_enable();
/* configure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
fwdgt_config(5,FWDGT_PSC_DIV64); //t = (1/0.625)x(5) = 8ms
fwdgt_counter_reload();
fwdgt_enable();
}
程序应用:
int main(void)
{
FWDGT_Init();
while(1)
{
task_fwdgt_reload();
}
}