2.13 软件陷阱实例
在单片机系统的实际应用中,系统的抗干扰能力显得非常重要。提高单片机系统的抗干扰能力除了采取硬件抗干扰手段外,也可采用软件抗干扰的手段,并且软件抗干扰具有设计灵活、节省硬件资源、成本低的优点,加以合理运用也能起到很好的抗干扰效果。
软件抗干扰的措施主要有指令冗余、软件陷阱、软件“看门狗”等。本节通过软件陷阱实例介绍如何编写软件抗干扰程序。
本节首先介绍什么是程序跑飞以及软件陷阱技术,接着讲述软件陷阱在程序中的位置,最后将给出软件陷阱程序实例并对软件陷阱程序进行分析。
2.13.1 基础知识
单片机程序正常运行时,程序计数器PC始终指向正在执行指令的下一条指令第一个字节的程序存储器单元地址,这样就保证了单片机能够正确地读取每一条指令的各个字节,即CPU先读取操作码,再读取操作数(如果有操作数字节的话)。在8051单片机中,程序计数器PC的寻址范围是0000H~FFFFH,共64KB。用户应用程序中,根据系统要求,规定了程序运行的唯一路径。这体现在系统上电后,程序计数器PC有唯一的变化历程,保证了程序正常、有序地运行。程序跑飞是指系统受到某种干扰后,程序计数器PC的值偏离了给定的唯一变化历程,导致程序运行偏离正常的运行路径。
程序跑飞的因素及后果往往是不可预计的。但在很多情况下,程序跑飞后PC指向未写入数据的Flash程序存储器。由于没有写入数据的Flash程序存储器的内容为0FFH,机器码0FFH对应的指令为MOV R7,A,所以系统不断地执行MOV R7,A指令,并很快会执行到程序存储器的最末尾,进入死循环而导致死机。这时,采用软件陷阱技术能有效引导跑飞的程序尽快退出死循环并迅速复位。
2.13.2 软件程序设计
软件陷阱程序主要包括程序跑飞的捕获和复位处理两部分,下面对这两部分分别给出程序实例并对程序做详细解释。
1.软件陷阱
软件陷阱程序段如下:
NOP
NOP
LJMP ERR ;跳转到软件陷阱复位处理程序
当单片机系统工作正常时,单片机不会执行软件陷阱程序段。但是当单片机系统受到干扰而程序跑飞后,由于程序计数器PC值错误,破坏了正常的指令格式,导致执行非正常指令,从而执行软件陷阱程序段,落入软件陷阱,将跑飞的程序引导到软件陷阱复位入口地址ERR。
软件陷阱程序段中的连续2条NOP指令实际上也就是指令冗余的抗干扰方法,目的是为了增强LJMP ERR被执行的能力,即LJMP ERR指令不会被冲散,当程序跑飞后会得到完整地执行,从而使跑飞的程序纳入正常轨道。
2.软件陷阱在程序中的位置
下面将根据软件陷阱在程序中的不同位置,给出软件陷阱程序的具体实例。
(1)未使用的中断向量区
在未使用的中断向量区放上软件陷阱,就可以及时捕捉到错误的中断。在未使用的中断向量区放置软件陷阱的实例如下:
ORG 0000H
LJMP MAIN ;程序跳转到主程序入口
ORG 0003H
LJMP X0_INT ;程序跳转到外部中断0中断服务程序入口
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
ORG 000BH
LJMP T0_INT ;程序跳转到T0中断服务程序入口
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
ORG 0013H
LJMP X1_INT ;程序跳转到外部中断1中断服务程序入口
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
ORG 001BH
LJMP T1_INT ;程序跳转到T1中断服务程序入口
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
ORG 0023H
LJMP S_INT ;程序跳转到串行口中断服务程序入口
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
(2)子程序后面
当用户应用程序正常运行时,这些软件陷阱程序段并不会执行,但是当单片机受干扰而使程序失控时,程序计数器PC指针一旦落入这些陷阱区,就可以马上将跑飞的程序拉回到正确的轨道。
;……
RET
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
(3)中断服务程序后面
;……
RETI
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
(4)在表格区
TABEL:
DB ;……
DB ;……
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
(5)未使用的程序存储器空间
如上文所述,程序一旦跑飞到未使用的程序存储器空间,将会飞流直下,一般在一些固定的地址加入软件陷阱,捕获跑飞的程序。
ORG 1000H
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
ORG 1FFBH
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
3.复位处理程序
跑飞的程序被软件陷阱捕捉后,可以直接使用LJMP 0000H指令使程序回到正常的执行状态。但是由于程序跑飞前的单片机状态不确定,一些情况下直接使用LJMP 0000H指令使程序返回正常状态并不可靠,因此最好加入一段错误复位处理程序,将单片机恢复到正常状态。错误复位处理程序实例如下:
ERR:
CLR EA ;关闭中断 (1)
MOV DPTR,#ERR1 ;准备第一次返回地址 (2)
PUSH DPH ; (3)
PUSH DPL ; (4)
RETI ;清除高级中断激活标志 (5)
ERR1:
CLR A ;准备复位地址0000H (6)
PUSH A ; (7)
PUSH A ; (8)
RETI ;清除低级中断激活标志 (9)
使用以上的错误复位处理程序主要是由于程序受到干扰而跑飞是随机发生的,如果程序跑飞前正处于中断状态,直接跳转到程序起始位置0000H并不能使单片机回到正常工作状态(中断激活标志未清除)。在8051单片机中,能够清除中断激活标志的指令只有RETI指令,因而可以利用RETI指令使单片机回到正常状态。而在最严重的情况下,程序跑飞时,单片机正处于两级中断嵌套的状态,此时需要通过两个RETI指令才能使单片机回到正常状态。下面我们看看上面的错误复位处理程序实例是如何使单片机回到正常状态的。
程序(1)关闭中断,使错误复位处理程序不受到中断信号的影响。程序(2)~(4)将ERR1的地址压入堆栈中。程序(5)使用RETI指令清除高级中断激活标志,同时使程序跳转到ERR1处继续执行。程序(6)~(8)将地址0000H压入堆栈中。程序(9)再次使用RETI指令清除低级中断激活标志,同时使程序跳转到起始位置0000H。通过这一系列操作,才能真正可靠地将单片机恢复到正常状态,并从程序起始位置重新开始执行。
2.13.3 技巧总结
- 本实例详细解释了软件陷阱的作用、原理,并给出了软件陷阱的程序实例。本实例需要注意以下两点。
- 在程序的恰当位置放置软件陷阱,可以在一定程度上加强抗干扰能力。但是软件陷阱的作用是有限的,在抗干扰要求高的情况下,还应当和“看门狗”等硬件抗干扰手段结合使用。
- 软件陷阱最好不要将程序直接引导向启动地址0000H,而应当加入一段如上文所示的错误复位处理程序。在错误复位处理程序中,除通过本实例给出的这些指令操作使单片机的状态恢复正常外,还可加入一些保存关键数据的操作。