【简介】
看门狗模块在开发中是一个经常被使用的模块,确保软件运行异常卡死或者跑飞会触发看门狗超时复位的一种异常恢复机制。 开始之前我们先看下S32K146的看门狗框图。
从上述框图可以看出看门狗模块的功能还是比较清晰的,我们结合框图很和开发手册梳理下内部看门狗IP的功能。
【看门狗的计数器的输入时钟信号单元:】
对应的时钟输入可以看出通过CLK信号来选择看门狗定计数的输入时钟源
可以配置为如下四路时钟
为了配置看门狗计数器的超时时间长短,在输入信号的后端加入了256 分频设置,通过控制寄存器的PRES信号来控制。
【看门狗计数单元:】
时钟信号经过256分频或者不分频设置后,输入到内部计数器模块更新计数从图中可以看出对应的计数器为16bit,计数器更新的同时会跟配置的timeout寄存器或者窗口寄存器配置的值进行比较,如果触发异常则会输出控制信号给到下级的控制单元。
以下分别对应在timeout 和 window 模式下的超时计数器及窗口上下限控制寄存器的配置。
并通过WIN信号来控制Timeout 或者 window 模式。
【看门狗控制单元:】
看门狗的超时发生或者窗口模式的异常事件会送到后端的“Control Logic”,该单元会根据控制信号里触发CPU直接重启或者触发中断信号通知CPU然后延迟128个bus clock 在进行重启。
如果开启了中断,则会延迟128个bus cycle 在进行重启,对应手册上的描述如下。
【S32DS配置】
有了上述的理解我们使用S32DS配置看门狗模块,配置时钟选择内部SIRC 8M时钟进行256分频,8000000/256 = 31.25KHZ 时钟计数,超时时间配置为2S = 2000ms/(1000ms/31250) = 62500 ,对应S32DS配置如下
对应初始化配置代码如下
/** * @page misra_violations MISRA-C:2012 violations * * @section [global] * Violates MISRA 2012 Advisory Rule 8.7, External variable could be made static. * The external variables will be used in other source files in application code. * */ /* WDOG user configuration 0 */ const wdog_user_config_t WDOG_Cfg0 = { .clkSource = WDOG_SIRC_CLOCK, .opMode = { false, /* Wait Mode */ false, /* Stop Mode */ false /* Debug Mode */ }, .updateEnable = false, .intEnable = true, .winEnable = false, .windowValue = 0U, .timeoutValue = 62500U, .prescalerEnable = true /* WDOG prescaler */ };
编写如下测试代码验证watch dog 的超时功能。
/******************************************************************************************************** * Private Function Declarations * *******************************************************************************************************/ unsigned int wdg_test(char argc,char *argv[]) { status_t ret; /* Init wdg */ ret = WDOG_DRV_Init(WDOG_CONFIG_1_INST, &WDOG_Cfg0); if(ret != STATUS_SUCCESS) { LOG_E("Wdg init failed %x",ret); } uint8_t count = 8; while(count--) { vTaskDelay(1000); /* Reset Watchdog counter */ WDOG_DRV_Trigger(WDOG_CONFIG_1_INST); LOG_I("feed dog"); } return 0; }
上述测试代码在停止喂狗后2s 后发生了重启,跟配置的2S超时配置保持一致