打印

嵌入式系统异常复位定位思想【自己学习记录,如有雷同纯

[复制链接]
4177|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
飞雪季节|  楼主 | 2007-7-3 10:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
嵌入式系统异常复位定位思想 
 
2007-05-11 22:06:05 
 
大中小 
    凡是靠软件支撑的嵌入式系统都会发生复位现象,如果没有发生过复位,那么很有可能会发生另外一种更糟糕的情况,系统吊死,陷入了死循环,你根本就不知道它到底运行到了哪里。也有可能是你的能力所限,异常中断没有写好,虽然处理器发生了异常,但你没有去处理。所以从这来看,发生了复位还不算最坏,至少系统能恢复,只要不是经常发生,没准你的客户始终都发现不了,还会夸你的产品很好。
    现在的处理器已经做的很好,只要你对它的工作原理稍微有点了解,那么你就可以写出适当的代码,当发生异常的时候,根据现场保留的故障诊断信息,来定位出错的根源。至于为什么会复位,本质来说是你的软件自己让它复位的(最常用的是看门狗),常见的DEMO程序,异常中指分之,只是些个死循环,在实际的产品中是万万不能这样操作的。
   对于各种处理器,异常一般会有3种:
    1)预取指中止,也就是说取得指令地址不正确,因为处理器都会有一些保留地址,这些地址CPU是不能访问的,万一进行访问,就说明程序执行出错了。
    2)数据中指,也就是说访问的数据地址不正确,原因同上。
    3)指令错误,顾名思义,指令译码出错。
   在如上的三种情况,软件都必须要处理,简单的话,开看门狗,对系统进行复位,负责任的话,可以保留现场信息,留着后面的程序员来定位原因。
   当然还有高档的CPU,这种异常是一种特殊的处理,比如地址重映射等,这里不关注,需要特殊处理。
    对于一个稍微复杂点的嵌入式软件,它会专门作一个故障诊断的功能,当系统发生警告或者错误的时候进行特殊处理,比如内存不足,当错误积累到一定程度,系统自动复位,这种是一种纠错处理,处理器并未发生异常。
 
    以ARM7为例,我们知道在用户模式下我们常用的R0-R15以及CPSR共17个寄存器,其中R15是用作PC指针,R14用作函数返回指针,R13用作堆栈指针。那么发生异常后我们怎么做才能给以后提供足够的定位信息呢?
    1)根据异常模式下的R14找出USER模式下的PC指针,因为这个时候已经发生了处理器模式切换。
    2)切换到特权模式访问用户模式的SP指针,通过SP指针,保存堆栈数据到RAM(注意这片RAM开机不要被初始化,可以通过编译配置完成)。
    3)复位系统,开机检测到异常开机,把诊断信息记录到文件系统。
    4)用工具读出文件到PC,对比编译的符号文件,一般是MAP文件,或者使用其他工具,进行分析,不出意外,很快就能找出复位的原因。
 
    有些处理器会有指令执行过程中总线记录的环形RAM,每当指令执行,总线访问的地址,以及访问方式会实时记录下来,当有异常发生的时候,这片RAM区域会自动锁死,只能访问,不能改写,同样可以记录下来,保存到文件系统,供以后分析。
 
   其实这里还没有说为什么处理器会产生异常,从我来看,绝大多数的异常内存越界引起的,比如
     U32  buf[1];
     for(i = 0; i < 10; i++)
     {
         buf = 0xFFFFFFFF;
     }
   
   上述代码在语法上是没有任何问题的,但执行的过程中就会发生异常。因为局部变量(buf[])都是从堆栈中申请的,下面的那个循环就会把堆栈中其他地址的内容都改写成0xFFFFFFFF,如果当地址访问的话就发生了错误。
   还有最常见的堆栈溢出,也就是堆栈空间开小了,申请的局部变量跑到堆栈以外了,改写了其他地方的RAM,引起处理器异常。
 
     以上只是简单说一下原理,具体仍需要对处理器稍微有些了解,不是朝夕就能立刻生效的,ARM的话可以参考《ARM体系机构与编程》,其实这本书就是ARM公司的英文文档的精简翻译,看看英文原版也未尝不可。 
 

相关帖子

沙发
high| | 2007-7-3 11:18 | 只看该作者

不错

使用特权

评论回复
板凳
lpf336| | 2007-7-4 17:31 | 只看该作者

顶一下

使用特权

评论回复
地板
tjsheep| | 2007-7-4 17:50 | 只看该作者

自己写的么?

使用特权

评论回复
5
飞雪季节|  楼主 | 2007-7-4 20:59 | 只看该作者

呵呵,如假包换,

   前提是工作中也接触过一些大型嵌入式软件的一些异常处理方法,再结合ARM的一些东西,觉得写出来对很多人是有好处的,开始我是放在别的地方,1个月过去了也没人看,所以就粘了过来,至少我以前是没有意识到这些细节的,也是工作中一个逐渐渗透的过程。
   嵌入式中关于异常的处理总的来说万变不离其中,区别就在于细节和分析工具的深入。
   能力所限,再深入咱也写不出来了。

使用特权

评论回复
6
aiqin| | 2007-7-17 10:04 | 只看该作者

To:tjsheep

To:tjsheep 
千万不要怀疑飞雪季节的水平,他发的帖子我都看过,仰慕他老久了!!

另外谢谢飞雪季节每一次的无私奉献!

使用特权

评论回复
7
太阳之母| | 2007-7-17 21:59 | 只看该作者

受益受益!

使用特权

评论回复
8
sockit| | 2007-7-21 16:33 | 只看该作者

赞~

使用特权

评论回复
9
db10| | 2007-7-22 10:49 | 只看该作者

写得不错 我也顶你一下

 能不能把你说的:
     以ARM7为例,我们知道在用户模式下我们常用的R0-R15以及CPSR共17个寄存器,其中R15是用作PC指针,R14用作函数返回指针,R13用作堆栈指针。那么发生异常后我们怎么做才能给以后提供足够的定位信息呢?
    1)根据异常模式下的R14找出USER模式下的PC指针,因为这个时候已经发生了处理器模式切换。
    2)切换到特权模式访问用户模式的SP指针,通过SP指针,保存堆栈数据到RAM(注意这片RAM开机不要被初始化,可以通过编译配置完成)。
    3)复位系统,开机检测到异常开机,把诊断信息记录到文件系统。
    4)用工具读出文件到PC,对比编译的符号文件,一般是MAP文件,或者使用其他工具,进行分析,不出意外,很快就能找出复位的原因。


 写个经典的代码例子??

使用特权

评论回复
10
hollly| | 2007-8-1 11:35 | 只看该作者

恩,不错。。。

使用特权

评论回复
11
lxbetty| | 2007-8-1 16:50 | 只看该作者

牛人...有时间多来....

使用特权

评论回复
12
pppking| | 2007-8-23 09:05 | 只看该作者

受益

使用特权

评论回复
13
btiger2000| | 2007-8-23 10:34 | 只看该作者

不错!

使用特权

评论回复
14
fishingok| | 2007-8-23 18:48 | 只看该作者

不懂意思,也觉得好

使用特权

评论回复
15
lshlin| | 2007-8-25 00:22 | 只看该作者

不错,帮顶

使用特权

评论回复
16
雨夜屠夫| | 2007-9-14 15:57 | 只看该作者

不错,学习~

使用特权

评论回复
17
cszhaoqm| | 2007-9-20 22:14 | 只看该作者

内存越界,野指针...致命问题!

使用特权

评论回复
18
biao.l| | 2007-9-23 12:57 | 只看该作者

不错,顶一下

   

使用特权

评论回复
19
embed9527| | 2007-9-24 15:29 | 只看该作者

软件识别指针越界否?

在内存管理方面软件能不能有效地识别越界?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

13

帖子

0

粉丝