涉及版权,欲用于商业用途,务必与作者联系,联系方式见文尾
嵌入式系统中常见的对于系统异常捕获的方式有两中,一种为异常捕获,另外一种为打桩,本文针对后种方法进行简要介绍
打桩通常用于对系统堆栈的跟踪以及出错信息的捕获,常见的方式可以通过在函数入口和出口分别操作并将其值存放到一定位置来实现;另外一种方式为低级的汇编方式,在函数入口处仅仅实行一个函数,该函数完成所有的需要进行的操作。
本文主要讲述后一种,实现平台为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]; SYSCTRLTable sysCtrlTbl[MAX_RECORD_TIME]; EXCTRAPTable excTbl[MAX_RECORD_TIME]; } SwitchTable; ***************************************************/ /******************************************************* # 该函数负责在函数执行之后返回,作堆栈恢复的一些操作 # 调用进入的参数: r0,r1,r2,r3 可以作入参,返回value # r4~r8可以作变量寄存器 # 该处理使用 r0,r1 ********************************************************/ _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 # 该处理使用 r4,r3, 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
cpu的信息表
sysctrl的信息表
exec信息表
/*开始记录*/
QQ:26764135
伊妹儿/麦思恩:liam7953@yahoo.com.cn
刚涉及XScale 芯片,有不妥之处,请多指教!!!