以data abort 为例
Data_Abort_ISR MOV a1,#DATA_EXCEPTION_TYPE ; Set type DATA_ABORT (4) MOV a2,lr saveException MRS a3,CPSR ; Pickup current CPSR BIC a3,a3,#MODE_MASK ; Clear the mode bits ORR a3,a3,#SUP_MODE ; Prepare to switch to supervisor mode (SVC) MSR CPSR_cxsf,a3 ; Switch to supervisor mode (SVC) LDR a4, SYSTEM_FATAL_ERROR BX a4
SYSTEM_FATAL_ERROR实际是函数stack_system_error的地址
在stack_system_error函数中,首先会切换sp到一个专门为异常处理预留的内存地址上,然后根据异常传入的类型填充必要的参数后调用fatal_error_handler。
kal_fatal_error_handler(kal_char *error_message_ptr, kal_uint32 error_code, kal_uint32 os_error_code)
{
DisableIRQ();
error_param_g.param1 = (kal_uint32)error_message_ptr;
error_param_g.param2 = (kal_uint32)error_code;
error_param_g.param3 = (kal_uint32)os_error_code;
fatal_error_handler((kal_uint8 *)error_param_g.param1, error_param_g.param2, error_param_g.param3);
}
在fatal_error_handler中
{
/* lockout all interrupts */
DisableIRQ();
/* mask all interrupts */
IRQDirectMaskAll();
/*
* NoteXXX: To avoid system hang in the exception handler,
* watchdog remains active while handling exception (if it is enabled).
*/
WDT_Restart2();
/* increase the coutner */
INT_Exception_Enter++;
/* determine if multi-level exception*/
if (INT_Exception_Enter >= 2) {
tst_sysfatal_trace((kal_uint8 *)"Caution: Possibly Endless Nested Exceptions!");
ex_reboot();
}
//以下开始准备得到reset时的系统状态。
/*
* I. Initialize the exception log.
*/
/* reset hardware */
ex_reset_hw();//dma_recover_all,L1Audio_ResetDevice,L1D_PauseDSP
/* re-start WDT again */
WDT_Restart2();
然后得到当前task,并将其优先级设为0,最高
/* get the current thread id */
current_thread = kal_get_current_thread_ID();
/* determine if the current executed task is a TASK, not a HISR */
if ((current_thread != NULL) && (kal_if_hisr() == KAL_FALSE)) {
/* raise the task priority level to the highest */
kal_change_priority((NU_TASK *)current_thread, 0);
}
/* setup param */
param.ext = KAL_FALSE;
param.e1 = param.e2 = param.e3 = 0;
param.dump_param = NULL;
/* initialize the exception log */
/* determine if ARM pre-defined exceptions */
if (err_code < ASSERT_FAIL_EXCEPTION) {
param.type = (exception_type)err_code;
param.code1 = (kal_uint32 *)&os_err_code;
param.code2 = 0;
ex_init_log(¶m);
} else
//在ex_init_log中会取得当前版本信息,当前时间,当前系统堆栈信息,当前task状态,hisr状态
然后
/* output the exception log */
ex_output_log();
最后重启系统
/* reboot silently */
ex_reboot(); //使用watchdog来重启系统。
}
在系统重启后有如下一段代码
; /* Check if abnormal reset */
LDR a1,ABN_RST_PTR
BL INT_SystemReset_Check
在INT_SystemReset_Check中会读取地址为0×80040018 的寄存器的值并且同0×0ffa进行比较不相等就返回否则进入kal_fatal_error_handler
关于0×80040018的这个寄存器,datasheet上如下描述Watchdog Timer Reset Signal Duration Register。This register indicates the reset duration
When Watchdog timer times out
关于这段代码,猜测是因为有可能是系统因为挂起而没有reset watchdog寄存器导致重启,这里就可以进行log的抓取。



















