智能化系统的watchdog功能

🏠 首页 《无线电》杂志 1997年 🔗 第9期 🔗 第26页 分类:无线电技术自学经验交流 🔗 陆小华 🔗, 周振安 🔗

一、智能化系统中Watchdog功能设计的必要性

在智能化系统中,监控软件是系统的中枢及核心。然而有经验的系统工程师都知道,系统监控软件的运行总是要受到内部或外部的电磁干扰而经常“死机”。

由此看来,要提高系统运行可靠性,一方面尽可能提高系统硬件的抗干扰能力,减少系统监控软件运行时,出现“死机”的机会。另一方面是找到一种有效的方法,使系统一旦出现“死机”能够自动恢复正常。这就是人们通常所说的“看门狗”功能,即watchdog功能。

二、Watchdog功能实现的基本原理

watchdog功能实现的基本思想是利用一个计数器来跟踪CPU的运行,一旦发现“死机”,立即将CPU强行复位,使其恢复正常。Watchdog电路的基本结构通常由一个带复位清“0”控制端的定时计数器和相应的指令或软件组成。结构如图1所示。定时计数器对外部时钟源进行计数,溢出时可产生进位脉冲。定时器的清“0”控制端CLR受CPU的I/O口控制,当CLR无效时,定时器将不停地对外部时钟源进行计数,且每隔一固定周期产生一个进位脉冲。该进位脉冲通过单稳电路展宽后用作CPU的复位信号。如果仅是如此CPU将会周期性地被强行复位,这不是我们的最终目的。我们的目的是要求仅当CPU在出现“死机”时才被强行复位,而正常工作时不应受到这种干扰。这可通过在系统监控软件中插入指令,使CPU执行对定时器清“0”的功能,只要指令插入的位置适当,使得监控程序在正常运行时每隔一固定时间就能对定时器清“0”一次。当这个固定时间小于定时器的定时值时,该定时器不等计满就被清“0”,因而总不会产生进位脉冲,CPU也就不会被强行复位。当系统受到干扰,使监控软件陷入“死循环”时,则监控程序不能按时给定时器清“0”,定时器计数满后就会产生溢出脉冲对CPU强行复位,使系统进入正常状态,即“死机”自恢复功能。

图1
图1 🔍原图 (561×314)

上述的基本设计思想在具体实施时还必须注意以下几个问题:

1.定时器的清“0”指令插入位置一定要适当。所谓插入位置适当是指:①两次清“0”的最大时间间隔不能超过定时器的溢出周期;②一些中断服务程序要专门插入定时器清“0”指令;③一些条件分支转移循环程序中要专门插入定时器清“0”指令。

2.定时器的定时时间要设计适当。一般监控程序总是具有一定周期性,即按一定周期循环执行,要保证定时器的定时周期大于监控程序的循环周期,以便于插入清“0”指令,否则很难考虑完善。

3.定时器的计数过程和时钟源最好都由硬件产生,不受监控软件影响,例如不要用可编程定时器来实现。

4.定时器的进位脉冲必须足够宽才能用作CPU的复位脉冲,一般CPU复位脉冲宽度不应低于10ms,而定时器的进位脉冲C\(_{Y}\)宽度又受时钟源周期影响,时钟源频率较高时,CY较窄;时钟源频率较低时,C\(_{Y}\)较宽。无论如何,CY直接用作CPU复位总是不可靠的,一般可用单稳电路的适时作用对C\(_{Y}\)展宽,保证CPU能可靠复位。

三、watchdog功能实现的几种方案

实现watchdog功能的具体方案多种多样,下面介绍几种可行方案。

1.利用单片机内部的监视定时器设计Watchdog功能。

一般16位单片机内部都带有监视定时器,设计时只须在软件中插入适当指令即可。现以Mcs-98系列单片机为例介绍这种类型的watchdog功能的实现。

所谓监视定时器,它与普通的定时器稍有不同,其主要特点表现为:①其计数时钟源固定为系统时钟提供(有些经过适当分频):②溢出时直接使CPU复位,而不设置中断向量;③启动计数只能靠指令,停止计数只能靠复位。对8098单片机来说,片内的监视定时器是一个16位二进制计数器,因而最大计数范围为64k,当系统时钟为12MHz时,监规定时器的计数时钟源为4MHz,则监视定时器的最大定时时间为\(\frac{1}{4}\)×10\(^{-}\)6s×64×103=16ms。

8098单片机的监视定时器靠指令写入常数来复位并启动计数;这两条指令为:

LDB 0AH,#1EH;

LDB 0AH,#0EH;

系统初始化程序可以插入这两条指令来启动监视定时器计数,在系统主程序的循环套内插入这两条指令使监视定时器清“0”并重新计数。系统监控软件的框图结构如图2所示。注意主程序的循环周期应不超过16ms。

图2
图2 🔍原图 (341×801)

以上介绍的方法只限于片内包含有监视定时器的16位单片机,而对目前广泛使用的8位单片机来说,其内部一般都不含专用的监视定时器。此时可利用普通定时器的中断响应能力,在软件上采取适当措施,也同样可以实现watchdog功能。

现以8031单片机的T\(_{0}\)计数器为例简要说明其实现过程的大致思想。

首先,T\(_{0}\)计数器也能对系统时钟直接计数。当T0计数产生溢出时,它虽不能像监视定时器那样直接复位CPU,但它能激活中断。如果在中断服务程序中插入适当指令,使得CPU的程序计数器(PC)在中断退出时指向起始位置,则也能起到复位效果。称其为“软件复位”。可以在中断服务程序中写入下列指令实现“软复位”:

MOV A,#00H;

POP R\(_{0}\);将栈顶保存的产生“死循环”处的地址

POP R\(_{1}\);弹出保存在R0,R\(_{1}\)

PUSH A;将0000H压入堆栈

PUSH A;

RETI;中断返回时,PC值已修改为0000H

执行上述中断服务后,CPU的PC值就被修改为0000H,程序又开始从头执行。

这种思想用到程序调试中也很有用,很容易找到程序的“死循环”的故障位置。

其次,在程序段中为T\(_{0}\)写计数初值时,可通过写入不同的计数初值来控制监视时间的长短。而且,修改栈顶时也不一定要选PC=0000H,可根据实际需要将PC引到适当位置。

如果我们在中断服务程序中安排的是口输出指令,每中断一次,输出一个脉冲,然后再用该脉冲经单稳电路来展宽去复位CPU,则也同样能起到“硬复位”的效果。

2.直接按图1所示原理框图由外部硬件构成watchdog电路。

图1的框图构成原理已在上文说明,具体实施时可根据需要选择硬件。假设CPU为8031单片机,I/O口为P1.0,时钟源由32.768kHz晶振产生,定时计数器选用12位二进制计数器芯片,可产生的最大定时时间为125ms,能够满足循环周期在120ms以下的监控软件要求。

单稳电路选用74HC123芯片,延时常数由RC确定,一般RC>10ms即可。

这种方案虽然增加了系统的硬件成本,但所设计出的“死机”自恢复功能比较可靠。

3.利用MC146818实时钟芯片内部的报时功能实现系统的Watchdog功能。

上述两种实现方法监视时间一般都不能做得很长。有时系统的监视定时器的值要求较长,例如在秒、分甚至更长的数量级,即使用方案2可以实现,也会使系统硬件成本增加。下面介绍的这种方案仅使用了MC146818时钟芯片的报时功能,无须另加硬件就能实现监视时间大于1秒以上的任意值。

有关MC146818的内部结构及接口硬件,参考资料很多,读者可以很容易查到,这里限于篇幅就不赘述,主要谈一下设计思路,读者根据这个思路可以自由发挥,肯定能实现高质量的watchdog功能。

仔细阅读MC146818芯片的使用说明后就能发现,在芯片内部有00H~0DH共13个字节的专用存储单元和0EH以上的公用存储单元。其中0AH~0DH为4个控制寄存器,专用于保存命令和状态控制字,00H~09H共10个字节用于存放实时时钟及日历等时间信息。特别要指出的,01H,03H,05H三个单元可分别用于保存秒报时、分报时、小时报时信息。这三个单元的信息是由指令写入的,根据写入信息的不同,可以实现不同功能,即:

若在上述三个单元均写入C0~FF代码(任取),则每秒产生一次中断;

若在03H,05H单元写入C0~FF代码,则每分钟产生一次报时中断;

若仅在05H单元写入C0~FF代码,则每小时产生一次报时中断;

若在01H,03H,05H三个单元都写入了具体的时间,则报时中断每天在这个确定的时间发出。

根据上述特征,我们可以在监控软件中每隔一固定时间执行一次这样一个子程序段,这个子程序段的功能是:①读取MC146818当前实时钟值;②当前时钟加上一个常数;③相加结果写01H,03H,05H单元。如果将MC146818芯片初始化为只允许报时中断,而将周期中断和更新中断都关闭,这样就会造成一种效果,使得监控程序每隔一段时间就修改一次报时时间,当监控程序正常运行时,不会产生报时中断,只要在当前时钟上所加的这个常数大于两次执行上述子程序段的最大时间间隔。

如果程序“死机”,但实时钟仍在正常运转,则当时钟运行到报时时间值时,就会在MC146818的IRQ脚输出一个正脉冲(即报时中断),这个正脉冲被展宽后来复位CPU,则实现了系统“死机”自动恢复功能。(周振安 陆小华)