我正在设计一个裸机 STM32 固件,它必须检测挂起/丢失的代码并重置。我的方法是让每个中断基础进程(基本上是中断驱动的代码)在运行时增加自己的全局变量,然后在最高优先级的“主管”任务中检查以确保每个全局变量都在变化。如果任何一个变量停止变化,则允许 WDT 重置电路板。
这听起来是个好办法吗?还有其他更好的主意吗?
我正在设计一个裸机 STM32 固件,它必须检测挂起/丢失的代码并重置。我的方法是让每个中断基础进程(基本上是中断驱动的代码)在运行时增加自己的全局变量,然后在最高优先级的“主管”任务中检查以确保每个全局变量都在变化。如果任何一个变量停止变化,则允许 WDT 重置电路板。
这听起来是个好办法吗?还有其他更好的主意吗?
假设前台/后台“超级循环”架构,带有中断处理程序和单个主线程,那么我建议更好的方法是为每个中断实现超时。
例如,假设您已经实现了一个基本的系统滴答接口(在 Cortex-M 上使用 SYSTICK),其中有一个函数
tickms()
以毫秒为单位返回经过的时间。那么对于每个被监视的中断,您可能有一个枚举,例如:然后是一个数组,例如:
以及 API:
然后,每个中断通过重置其超时
wdgReset()
,主循环不断检查软件看门狗,如下所示:然后:
wdgCheck()
则将旋转,并且硬件看门狗将触发,wdgCheck()
,请注意,在 Cortex-M 上,您可以通过 NVIC 发出软件重置,因此您可以选择在软件看门狗到期时立即重置,而不是等待硬件看门狗。
显然,这只是一个伪代码大纲,纯粹是说明性的——它可以以多种方式进行改进和扩展。如果您要使用 RTOS,您可以类似地保护任务,其中监控器要么在空闲循环中,要么在优先级低于其他任何任务的任务中。
我建议的一个改进是拥有一个软件看门狗的动态注册表而不是静态数组,并拥有一个 API:
例如,任务和设备驱动程序可以独立添加自己的看门狗,并
wdgCheck()
迭代所有已注册的处理程序。任务甚至可以根据需要动态修改周期(例如,如果暂时禁用):首先,请注意,如果不允许任何任务挂起,那么最简单的方法就是相应地设置硬件看门狗定时器,因为钝的 MCU 复位是处理错误的可接受方法。
仅在以下情况下才需要软件监督:
为简单起见,我们假设每个任务最多允许消耗 x 毫秒,没有单独的超时。伪代码可能如下所示:
在某些系统中,您还可以在安全模式和操作模式之间切换,并且在出现错误时可以恢复到安全模式。