嵌入天地

----->>>>>嵌入式 文学 管理 米国 卡通 以及其他

公益广告:你可知道,看帖回复和评论是一种美德!

另,兄弟姐妹们,假如有技术问题交流,请直接发送到我的信箱!

博客园 首页 新随笔 联系 订阅 管理

涉及版权,欲用于商业用途,务必与作者联系,联系方式见文尾

嵌入式系统中常见的对于系统异常捕获的方式有两中,一种为异常捕获,另外一种为打桩,本文针对后种方法进行简要介绍

       打桩通常用于对系统堆栈的跟踪以及出错信息的捕获,常见的方式可以通过在函数入口和出口分别操作并将其值存放到一定位置来实现;另外一种方式为低级的汇编方式,在函数入口处仅仅实行一个函数,该函数完成所有的需要进行的操作。

本文主要讲述后一种,实现平台为Xscale,支持多重深度,稍加修改,可以实际支持多线程,该做法和代码如下并实际调试通过 

/

/*

modification history

--------------------

2005-3-28 17:35 william add track stack

*/

#define _ASMLANGUAGE

#include "vxWorks.h"

#include "asm.h"

 

       .EQU STACK_TRACE_INFO_BASE,0x08000000  /*sysMemRosTop*/

       .EQU STACK_TRACE_ASML_ZER0,0x0

 

/* 获取当前堆栈的返回指针并和当前信息一并填入相对应的地址空间INFO_BASE*/

       .GLOBAL  _sysTraceSaveCurLr    

/* 读取当前信息从INFO_BASE并恢复当前堆栈的返回指针并*/

.GLOBAL  _sysTraceResumeCurLr          

 

/**************************************

****            系统当前使用的数据结构      ****

typedef struct

{

    char                *FileName;

    UINT32              FileLine;

    UINT32              ParaPtr;

    UINT32              ReturnPC;

} STACK_RECORD;

 

定义在固定地址的执行信息索引

typedef struct

{

    UINT32          tableSize;            信息表大小          

    UINT8           CRC;                    校验和

    UINT8           nowUse;              当前使用            

    UINT8           unuse1, unuse2;  未使用字段  for crc 

    STable           *tablep;             当前使用表地址      

    STACK_RECORD    *callp;      当前调用栈顶地址    

 

    STable                    table[MAX_RECORD_TIME];            
                                                
cpu
的信息表       

    SYSCTRLTable       sysCtrlTbl[MAX_RECORD_TIME];    
                                                 sysctrl
的信息表

    EXCTRAPTable      excTbl[MAX_RECORD_TIME];        
                                                
exec
信息表     

} SwitchTable;

***************************************************/

 

/*******************************************************

# 该函数负责在函数执行之后返回,作堆栈恢复的一些操作

# 调用进入的参数:  r0,r1,r2,r3 可以作入参,返回value

#                   r4~r8可以作变量寄存器

# 该处理使用 r0r1                   

********************************************************/

_sysTraceResumeCurLr:

    /*获取SwitchTable的基地址*/

    LDR r0, =STACK_TRACE_INFO_BASE

    /*获取tablep(当前STable所在的地址)*/

    LDR r1, [r0,#0xc]

   

    /*向下减一个,获取第一个有效tablep地址*/

    SUB r1,r1,#0x10

   

    /*准备将该条目删除,将其地址作为当前地址*/

    STR r1, [r0,#0xc]

 

    /*读取返回地址,并写进入LR*/

    LDR lr, [r1,#0xc]

   

    /*清空该条目空间*/

    LDR r0, =STACK_TRACE_ASML_ZER0

    STR r0, [r1]

    STR r0, [r1,#0x4]

    STR r0, [r1,#0x8]

    STR r0, [r1,#0xc]

 

    /*跳转到相关返回地址开始执行*/

    MOV pc, lr 

 

/***********************************************************

# 该函数负责在函数执行后堆栈内容保存和函数执行的重新定向

# 调用进入的参数:  r0,r1,r2,r3 可以作入参,返回value

#                   r4~r8可以作变量寄存器

# 调用进入的参数:  r0 = 文件名指针, r1 = 行号,

#                   r0,r1,r2,r3

# 该处理使用 r4r3, r2 ,r1, r0                   

***********************************************************/

_sysTraceSaveCurLr:

    LDR r4, =STACK_TRACE_INFO_BASE

   

    /*获取tablep(当前STable所在的地址)*/

    LDR r3, [r4,#0xc]

    /*是否为0*/   

    CMP r3, #0x0

    /*检测堆栈*/

    BNE william_check_call_stack

   

    /*没用进行初始化,直接返回*/

    B   william_sys_save_exit

  
               /*开始记录*/

william_check_call_stack:

    /*装载ParaPtr内容*/

    LDR r2, [r3,#-0x8]

    CMP r2, #0x0

    BEQ william_save_to_top

    CMP fp, r2

    BLE william_save_to_current

    SUB r3, r3, #0x10

 

    B william_check_call_stack

                

william_save_to_top:   

    LDR r3, [r4,#0xc] 

 

william_save_to_current:   

    STR r0, [r3]

    STR r1, [r3,#0x4]

    STR fp, [r3,#0x8]   

 

    /*lr:return address 将返回地址写入固定偏移处*/

    LDR r0, [fp,#-0x4]

    STR r0, [r3,#0xc]

 

    /* trace_out地址存放在存放返回地址的地址处*/

    LDR r1, =_sysTraceResumeCurLr

    STR r1, [fp,#-0x4]

   

    ADD r3, r3, #0x10

    STR r3, [r4,#0xc] 

 

william_sys_save_exit:

    MOV pc, lr 

 


QQ26764135

伊妹儿/麦思恩:liam7953@yahoo.com.cn
       刚涉及XScale 芯片,有不妥之处,请多指教!!!

posted on   嵌入专栏  阅读(739)  评论(0)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示