公司的产品是用ARM7开发的,操作系统采用了uCos简化后的版本。前一阵子测试中发现产品不断无规律的复位,没有固定时间间隔,个体差异很大,很难摸索出规律来。这可是关系产品稳定性的大事,必须放下手边的事情集中精力对付这条“虫”!
如何对复位进行调试呢?首先要对复位进行分类。从引起复位的源头来看,可以分成外部复位和内部复位,内部复位的源头又可能由看门狗产生,也可能是由于异常所引起,甚至还有为了重置硬件所需的程序控制的复位。因此,第一步就是需要找到引起复位的源。看门狗复位比较好查,因为看门狗在复位时会设置标志。其他几种复位源就难以区分了,怎么办呢,只好自己设置标志了。实际上,RAM在CPU复位之后并不会清除数据,除非你的程序做了这样的事情(或者断电)。这就意味着可以在启动部分设置一个标志,通过将该标志来确定复位的源(或者记录复位前的任务ID等信息)。
很快,我们就发现复位是由看门狗引起的,这样接下来的问题就是定位问题代码。这也不是一件容易的事情,首先想到的是看门狗复位应该是由于超时所引起的。于是采用前面的办法将复位前的状态信息打印出来,一步一步的跟踪。然而,令人迷惑的事情却出现了,复位点确似乎位于刚刚喂狗之后!疑惑之中,开始到处查询资料,最后发现是对LPC2214的文档没有看熟。对于LPC系列的ARM芯片而言,喂狗时需要两条语句。这两条语句则必须连续,不能中断,如果发生了中断则看门狗会直接复位。这就能够解释复位的问题了,因为在喂狗时没有关闭中断,如果此时发生了中断则有可能打断喂狗的指令,从而引起看门狗复位。于是在喂狗指令之前进行了关中断,喂狗之后再打开中断,问题就该解决了。
但是事实并非如此,虽然复位的次数好像少了一些,不过仍然存在复位的现象!这又是为什么呢?按照上面的步骤再做检查,发现已经不是看门狗复位了,而发生复位的代码点还是在喂狗指令处的情况较多。再次查找资料,终于发现了一些端倪。在LPC的文档中提到了伪中断的情况。由于LPC系列采用了流水线处理方式,当发生中断时,需要将流水线中的指令处理完毕后才能响应中断。这时如果在流水线中存在关中断的指令,则会造成CPU在响应中断时无法判断中断的状态和信息。按照文档的介绍,则这时候CPU会转向一个默认的中断处理程序。在我们的产品中,没有对默认中断处理程序的寄存器进行设置,即该寄存器指向的地址为默认值0x00。显然,当发生伪中断时则CPU将跳转到地址0x00运行,这就造成了事实上的复位。在程序中添加了伪中断处理程序,然后进行测试,终于没有再发现复位的现象了。
阅读(989) | 评论(0) | 转发(0) |