问题描述:
使用GD系列芯片进入debug模式,在程序执行到某个断点之后,再点击全速运行时,程序可能会退出debug模式。
原因分析:
进入断点后,看门狗不再喂狗。导致再全速运行时,看门狗计数超时,触发看门狗事件引起系统重启;
以下代码看门狗计时周期为1秒:
//初始化独立看门狗
//独立看门狗时钟为40KHz,
//预分频数为16,独立看门狗计数时钟频率=40KHz/16=2500Hz,计数1次耗时(1/2500)s
//重载值为2500,
//溢出时间为1s
void IWDG_Init(void)
{
#ifdef USE_WDG
fwdgt_write_enable();
fwdgt_config(2500*1, FWDGT_PSC_DIV16);
fwdgt_counter_reload();
fwdgt_enable();
#endif
}
//喂独立看门狗
void IWDG_Feed(void)
{
#ifdef USE_WDG
fwdgt_counter_reload();
#endif
}
遇事不决,翻看手册:
果然,诚不我欺,手册上介绍了处理这种问题的方法:
根据上述介绍的寄存器位,查找库函数:
/*!
\brief enable peripheral behavior when the mcu is in debug mode
\param[in] dbg_periph: refer to dbg_periph_enum
only one parameter can be selected which is shown as below:
\arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
\arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
\arg DBG_CANx_HOLD(x=0,1): hold CANx counter when core is halted(170_190 series only)
\arg DBG_I2Cx_HOLD(x=0,1,2): hold I2Cx smbus when core is halted
\arg DBG_TIMERx_HOLD(x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted
\arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted
\param[out] none
\retval none
*/
void dbg_periph_enable(dbg_periph_enum dbg_periph)
{
DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph));
}
“enable peripheral behavior when the mcu is in debug mode”当mcu在debug模式时使能外设动作。
“DBG_FWDGT_HOLD: debug FWDGT kept when core is halted”当内核停止时保持独立看门狗调试不被停止。
没错,就是这段代码!
总结:
为了避免在debug时导致调试异常,需要在看门狗初始化代码中增加如下代码:
void IWDG_Init(void)
{
#ifdef USE_WDG
dbg_periph_enable(DBG_FWDGT_HOLD);//内核停止时(调试模式),使看门狗定时器停止工作,避免调试时触发看门狗
fwdgt_write_enable();
fwdgt_config(2500*1, FWDGT_PSC_DIV16);
fwdgt_counter_reload();
fwdgt_enable();
#endif
}
dbg_periph_enable(DBG_FWDGT_HOLD);
目的是:在内核停止时(调试模式),使看门狗定时器停止工作,避免调试时触发看门狗
如此一来就可以避免因看门狗触发引起的调试异常问题;