分享老司机简化的MCU程序保护设计,新手都学着点!
扫描二维码
随时随地手机看文章
1 发生错的原因与现有对策
MCU在工作时会受到干扰,在一些空间场合,可能遇到粒子轰击而产生稳态的翻转,即所谓single event upset。而一般工业场合是电源传导干扰,受干扰时,电源电压会瞬间超出或者略微超出MCU的名义工作电压,线路的稳定性就无法保证。由于各单个逻辑电路工艺过程中总会有微小差异,电源电压的略微超出会在最弱的逻辑电路中造成指令读错误和数据读写错误。这种错误最终表现为数据的错误。
国外对DRAM出错的研究已做得很多,在参考文献中转述了出错的概率:“谷歌(Google)使用了大量服务器,2009年的大规模统计。出错的概率是2.5~7×10-11error/bit/h。”即8G RAM每小时会有5个错。
现在对于有功能安全要求的系统,安全等级为SIL2时,出错的概率应小于10-7”/h。现在控制器所用的MCU的Flash与RAM的大小已达128 K~1 Mb,参考上述概率,如果缺少程序的保护,将会有1M×7×10-11 error/h=7×10-5 error/h,这远大于功能安全要求的出错概率。
从功能安全的角度,系统中任何影响功能的错误都是应该被检测出来的,如果这个错误危及人类生命或造成设备的重大损失,那么就必须有防范的措施,必要时就必须纠正错误。然而要达到这种要求是很难的,需要付出很大的代价。以数据错误为例,人们常常重复计算多次,然后把占多数的结果代表正确的结果。这样,数据分享前的结果都要经表决,否则发现错会太晚,影响一致性。这就需要更多的硬件资源与开发成本。即便如此,如果作为表决器的环节仍是MCU的一个程序,它仍然可能会受错误指令的干扰,未能完全拦住错误。
为了节省成本,更多的应用并没有采用这种冗余与表决的方法。它们往往以不死机作为目标,只要不死机,由控制对象来的新信息就可以重算出新的正确结果。即使上一次算出的错了,其后果也只延续了一个采样周期。这种策略对有累积效应的应用是无效的,就像参考文献中讨论的积分功能会失败。又如运行结果与过程密切相关的应用,例如可编程控制器(PLC),数据的错误会导致控制逻辑的混乱。
保证不死机的主要措施是采用看门狗技术,如果程序走飞,在一定时间内没有复位计时器,计时器就会溢出,产生MCU的重新启动,重新初始化可以纠正损坏了的数据。看门狗技术是不管数据正确性的,因为指令错了程序未必走飞,而指令错了数据错的可能性极大。
2 错误现象与错误校正方案
MCU的指令在读取时发生错误就会产生不同的执行结果,在参考文献中以8051的MOV指令为例,当有一位读错时就变成跳转、除法、减法、交换、增1等等指令。实际上大部分MCU都会有指令错而执行结果错的问题,因为这些指令内没有检验错的机制。MC68HC11的LDA指令有1位错时可能转为加法、减法、送立即数到累加器B、送状态存器、送堆栈指针等指令。
假定数据字用D表示,生成多项式用G表示,Gm为最高阶的系数,等于1。那么习惯的做法在除到Dn位时,判断Dn值。若Dn=1,则将G和D的对应位对齐,用模2加法求取余数,Mn-i=Dn-i+Gm-i,用余数Mn-i代替原来的Dn-i移位。如果Dn=0,则不做加法,Mn-i=Dn-i,然后移位,也可以说用余数Mn-i代替原来的Dn-i移位。我们的目的是直接由D来产生余数,所以做了修改。修改方法是,当对齐后的Gm- i=1时,取Mn-i=Dn-i+Dn。当Gm-i=0时,对应项不做模2加。现在证明这两种方法是等效的:
Dn=0,Gm-i=0时,习惯方法Mn-i=Dn-i;修改方法Mn-i=Dn-i。
Dn=0,Gm-i=1时,习惯方法Mn-i=Dn-i;修改方法Mn-i=Dn-i+Dn=Dn-i。
Dn=1,Gm-i=0时,习惯方法Mn-i=Dn-i+Gm-i=Dn-i;修改方法Mn-i=Dn-i。
Dn=1,Gm-i=1时,习惯方法Mn-i=Dn-i+Gm-i=Dn-i+1;修改方法Mn-i=Dn-i+Dn=Dn-i+1。
现在对G=X4+X+1时8位指令的数据字用修改方法求取CRC各位的值,为了阅读方便,将数据字的各位用数字代表,例如7代表D7。参与模2加的各位就以各数字连写在一起。例如CRC的最高一位是7 532,它代表D7、D5、D3、D2的模2加法结果。通过建立真值表,它们最后都可以用组合逻辑来实现,所以在取指完成后就立即可以判出是否有错。