1、看门狗简介
单片机程序运行过程中,可能会遇到各种意外情况,导致程序运行出现故障。对于这些由于意外随机导致的故障,开发者不可能进行针对性的解决,而且这些意外情况大概率可以通过单片机复位(reset)得到解决。看门狗(WatchDog)就是在程序发生意外故障时,对程序进行复位的一个部件。
其实看门狗的本质就是一个计数器\定时器(timer)。以STM32的看门狗为例:其中的看门狗定时器(WatchDog Timer)具有向下计数的特性,给这个看门狗定时器一个值,例如66535(不过STM32好像给不了这么大的值,哈哈),定时器开始递减,如果定时器的值递减到0,则定时器触发单片机复位(这个动作一般叫看门狗超时复位)。而在程序正常运行时,看门狗定时器肯定不能reset单片机,所以在看门狗定时器递减到0之前,需要把看门狗定时器的值重新置为初始值(65535),然后看门狗定时器(WDT)重新递减计数,这个重置WDT值的动作就叫喂狗。喂狗的动作也需要函数才能完成(这个函数可以叫喂狗函数,需要周期性执行),可是如果程序出现意外故障,导致程序跑飞,喂狗函数得不到执行,看门狗定时器就会递减到0,从而reset单片机。
2、AUTOSAR规范下的看门狗
那么普通的看门狗和AUTOSAR规范下的看门狗有什么区别呢?下图截自autosar规范手册中WatchDogDriver部分的一句话,在autosar规范下,看门狗实现了servicing(个人理解其实就是喂狗,在规范中提到的trigger watchdog或者sevice watchdog基本都是指的喂狗)的时间和控制逻辑的解耦。
所以,AUTOSAR架构下的看门狗,分为3层,或者说3个模块(module):
(1)WatchDogManager
(2)WatchDogInterface
(3)WatchDogDriver
下图截自autosar规范手册中WatchDogDriver(WdgDriver)部分的一句话:可以看出WdgManager(WdgM)模块负责喂狗的逻辑控制(logical control)。
WatchDogInterface(WdgIf)模块主要用于提供接口给WdgM控制WdgDriver。
WdgDriver则是与硬件强相关的一层,个人理解其实就是Wdg的硬件驱动程序。
其中WdgDriver位于MCAL层,WdfIf和WdgM位于ECU抽象层。
3、WdgDriver
3.1、看门狗模式
下图截自autosar规范手册中WatchDogDriver(WdgDriver)部分,该表格表示WdgDriver有3种工作模式。
(1)off-mode:看门狗硬件失能。但是对于一些对安全性要求较高的系统,看门狗不能失能。
(2)slow-mode:看门狗具有较长的超时周期。
(3)fast-mode:看门狗具有较短的超时周期。
3.2、看门狗分类
看门狗分为内部看门狗(内狗)和外部看门狗(外狗)。内狗就是为MCU自带的看门狗,在autosar规范中,属于微控制器抽象层(MCAL Layer);而外狗就是位于MCU外部的看门狗,在汽车控制器上,外狗一般由供电芯片(SBC)提供,在autosar规范中,属于ECU抽象层。
如下两图所示:可以直接通过访问硬件来访问内狗;但是想要访问外狗,则需要通过SPI或者DIO(可以简单理解为GPIO)。
如下图所示:内狗和外狗需要满足相同的功能要求,提供相同的功能范围,所以具有语义相似的API。
3.3、看门狗如何喂狗
如下图内容所示:为了保证最小的时间抖动和延迟,喂狗由timer ISR(interrupt service routine),即定时器中断服务程序完成。
这里怎么理解呢?由前面的内容知道,看门狗的逻辑控制(logical control)由WdgM完成,但是WdgM控制WdgDriver需要通过WdgIf。如果由WdgM通过WdgIf控制WdgDriver完成喂狗函数,必然会照成较大的时间延迟,对于window dog(窗口看门狗)这种对时间精度要求较高的类型, 那肯定是不行的。所以一般使用Gpt(通用定时器)的中断进行周期性喂狗。
但是了解定时器中断的朋友应该知道,定时器中断的执行与主程序其实是互相独立的,即使主程序出现故障(比如进入死循环),定时器中断仍然会周期性执行。那么这肯定会导致定时器中断的周期性喂狗,即使在程序跑飞的情况下,也会执行,看门狗无法复位。
对于这个问题,我目前了解到的解决方法有两种:
(1)可以定义一个信号量“count”。在定时器中断函数中,每喂一次狗,count减1;在被监测的程序中,每执行一次,count加1。如果程序跑飞,被监测的程序无法正常执行,count的值就不会得到增加,又因为定时器中断会减少count,等count减到0,则停止喂狗,导致看门狗产生复位。
(2)每一次喂狗都减少看门狗的超时时间,并在程序中周期性调用API:Wdg_SetTriggerCondition
,恢复超时时间。例如,把看门狗的超时时间定为110ms,喂狗周期定为50ms。当看门狗开始运行,第一次喂狗时,会把超时周期调整至60ms(110-50),第二次喂狗把超时周期调整至10ms(60-50)。这时候看门狗就会面临喂狗周期大于超时时间的问题,但是如果程序处于正常运行状态,则会调用Wdg_SetTriggerCondition()这个函数,把超时时间重新调整至110ms,如果程序异常,没有调用这个函数,则会导致超时复位。
3.4、WdgDriver的主要API
(1)Wdg_Init:用于初始化看门狗硬件驱动。
(2) Wdg_SetMode:用于设置看门狗模式。
(3)Wdg_SetTriggerCondition:用于设置超时时间。(在TC275的mcal配置中,这个函数设置超时时间的同时,也会喂狗一次)
4、WdgIf
Wdgif层较为简单,这里只介绍其两个主要API。
(1)WdgIf_SetMode:供WdgM用于设置WdgDriver模式.
(2)WdgIf_SetTriggerCondition:供WdgM用于设置WdgDriver超时时间