本
文
摘
要
看门狗原理:在看门狗使能以后,需要在一定时间内对它进行喂狗,(一般在2S以内)如果没有及时喂狗,则系统会被复位,系统重新从main()处开始运行。
程序跑飞:当系统受到外部干扰导致总线错误或者数组溢出等错误时,会使CPU core的PC寄存器指向一个不可预知的位置。这里有两层意思:一是程序一直跑向一个不可预知的地方;二是:程序死在一个循环中。
在抗干扰实验中,我们经常会看到这样的现象,整个系统死机了,但是系统并不复位,即看门狗没有复位系统。为什么会出现这样的现象呢?可能原因之一就是程序死在了一个死循环中,并且在此死循环中执行了喂 *** 作,从而导致系统无法复位。所以喂 *** 作不能在可能出现死循环中执行,也不能在中断程序中执行。
现在的CPU体系结构都是基于中断的,如复位中断发生时,PC会指向RESET向量处;如定时器中断发生时,PC会指向定时中断向量处。在汇编代码中,RESET中断地址和定时器中断地址存放的会是JMP指令,跳向各自的中断向量函数。所以,main()和各个中断函数是平等的,从宏观上讲,main()函数和各中断函数是并行执行的,只是因为一上电就执行RESET指令,所以main()先运行,而其它的中断函数运行的条件并不是总是满足的,即使中断函数被触发执行,也并会像main()一样,会执行while(true){},所以我们经常看到的是大部分系统任务都在main()中运行,而其它中断任务处于一个从属的位置。理解了这样的前提条件,若喂 *** 作在一个1S为周期的定时中断中执行,即使系统跑飞(我们所说的跑飞大部分是指main()中的任务没有执行),但定时中断发生时,PC自动装载定时中断地址的指令,执行定时中断函数,执行喂 *** 作。定时中断执行完毕后,执行退栈操作,PC又指向了不可预知的位置,主程序仍没有执行(如果要main()重新开始执行,必须发生RESET),当定时中断再次发生时,又会在中断中执行喂狗,如此循环,从而导致系统不会复位。而实质上程序已经跑飞。
在程序中,我们经常会看到这样的代码:
While(flag){ if 某硬件条件{ flag = 0; } }如果硬件损坏或在干扰下硬件暂时失效,则flag不会被置0,则程序就会死在此循环中,此时就会导致整个系统复位。若在这段代码中有喂 *** 作,即使主程序跑飞,系统也不会复位。如何解决此累问题:一,在检测硬件条件一定次数之后,如果条件还不成立,则将flag = 0;二,置定时器标志,在检测硬件一定时间之后,不管条件是否成立,仍将flag = 0。
那么喂 *** 作应该在什么地方执行更合理,更能保证程序的健状性?
void main(){ InitSys(); while(true){ TASK1(); TASK2(); ... FeedWatchDog(); //执行喂 *** 作 } }整个系统中,此有只一处有喂 *** 作,即如果主任务没有被执行,则系统一定会复位。
如果TASK1,TASK2。。。。。。TASKn,运行时间加起来大于看门狗复位时间,可以在两个任务之间插入喂 *** 作。