尝试通俗的理解Autosar Wdgm(看门狗管理)
尝试 通俗一点理解一下Autosar的看门狗设计,纯属个人理解,有错误请指正。
看门狗的目的是:程序发生异常的时候(跑飞或者卡死),ECU能重启。
51单片机的看门狗设计
先回想下简单的51单片机看门狗是怎么设计的?常规的是这样的
1.先初始化启动看门狗,设置个复位时间,有个初始的counter假设是0.
2.代码跑起来,counter累加,跑完代码之后去喂狗也就是把这个counter恢复成初始值,也就是0.
3.如果正常跑,一直有喂狗程序去把这个counter清0,跑飞的时候没人去清,累加到阈值就复位。
void main()
{
看门狗初始化();
while(1)
{
函数A();
函数B();
函数C();
...
函数H();
喂狗();
}
}
这种设计,只有不卡死,在counter到达阈值之前去喂狗就不会发生重启。
那就有好多情况监控不到了:
1.函数A跑个5遍,
2.函数A运行完直接运行函数C,然后再去运行函数B
3.正常从函数A运行到函数C需要花费10ms,突然有一次只运行了5ms或者运行了20ms
Autosar的看门狗设计
简单的理解Autosar的看门狗只是在要喂狗之前加一些判断条件:
if(某些函数没有多运行或少运行) 而且
(函数是按照设计的逻辑去运行的(先运行A再运行B))而且
(函数1到函数2的运行时间在阈值内)
{
/*以上条件都满足*/
喂狗();
}
else
{
/*有条件不满足,停止喂狗,重启*/
}
这对应Wdgm的3个监测机制
Alive Supervision:监控周期运行的代码是否周期运行
Logical Supervision:逻辑监控,就是有些函数是要先跑A再跑B的,要严格的按照顺序跑
Deadline Supervision:截止时间监控,这个最类似51单片机的看门狗
机制1:Alive Supervision监控周期运行的代码
这个监控机制是用的最多的,举个不完全恰当的例子,假设很多人在跑步训练,每个人都分配一个监控员去监控跑步的情况,跑步的人在跑步的时候,跑一圈就打个卡,告诉监控员跑了一圈。
然后运动员跑的快2.5min跑一圈,中年人5min跑一圈,儿童6min跑一圈,
那60min内:
运动员应该跑24圈,监控员1认为运动员跑个24±1(23-25)都是正常的。
中年人应该跑12圈,监控员2认为中年人跑个12±2(10-14)都是正常的。
儿童应该跑10圈, 监控员认为儿童跑个10±3(7-13)都是正常的。
在autosar 看门狗里,
跑圈的人叫受监控实体Supervised Entity(SE),SE可以有很多个
判断周期60min是监控周期WdgMSupervisionReferenceCycle(SC),工具配置输入,每个SE可以有自己的判断周期
运动员打卡的点叫Checkpoint(CP),对应到实际代码就是在函数里执行一句xx_Checkpoint函数
运动员实际打卡的次数叫AliveIndications(AI)
理论上运动员应该打卡的次数24叫WdgMExpectedAliveIndications(EAI),工具配置输入,每个SE不一样
运动员允许的打卡次数偏差-1,叫WdgMMinMargin,工具配置输入,每个SE可以不一样
运动员允许的打卡次数偏差+1,叫WdgMMaxMargin,工具配置输入,每个SE可以不一样
假设运动员在一个监控周期内,跑了22圈,22<24-1,判定为失败,但是Wdgm允许你失败,只是先给你个黄牌记过,并不会重启,一个监控实体失败,总的监控实体也变失败,是或的关系。
监控员的状态叫局部的状态,每一个SE都有个自己的配置参数以及状态,
失败一次后,状态切换为failed,failed reference cycles加一。
当failed reference cycles超过2(工具配置)以后 ,状态切换为,expired,总监控员状态也变Expired,停止喂狗,重启。
再去看每个SE对应的监控员状态在autosar里叫Local Supervision Status,正常就是OK,失败就是failed,失败次数足够多就expired,更详细的可以去看官方文档。
总监控员并不监控每个受监控实体,它仅仅收集每个监控员的状态,综合判断得出自己的状态后控制是否停止喂狗。
机制2: Logical Supervision监控有严格执行顺序的代码
有些代码是要有严格的执行顺序的,比如ADC数据采集电压,那肯定要先成功采集到电压,再把电压传递给别的模块才能是最新的数据。
这个不展开举例了,官方文档上有举例,直接拿来用。
有一段代码假设如下,问你要怎么设计去监控它是按逻辑顺序执行的
i = 0;
while(i < n)
{
if (a[i] < b[i])
a[i] = b[i];
else
a[i] = 0;
i++;
}
先思考一下,怎么设计?
官方文档给的答案很简单粗暴,近乎是每一行设置个打卡点,然后设置好先后顺序。
假设代码里识别到CP0-5,就会判断上一次的CP点是不是CP0-3或者CP0-4,如果不是那就算发生异常了,记录一次异常,逻辑图如下
机制3: Deadline Supervision监控某段代码有严格时间要求的代码
一般不是周期运行的函数用这种机制来监测,就是开始的时候打个卡,结束的时候打个卡,然后计算开始到结束的运行时间是否超过阈值WdgMDeadlineMin~WdgMDeadlineMax
Wdgm逻辑图总览
就是OS周期性调度WdgM_MainFunction()函数去不断的每个受监控实体SE的信息,根据配置的机制方式,输出每个受监控实体SE的状态,然后综合的判断出总的监控状态,然后根据总的监控状态再去决定要不要喂狗。
Autosar官方文档下载
链接: AUTOSAR Documents.