嵌入式系统异常及编程.pptx
文本预览下载声明
5.1 ARM的异常;异常;ARM处理器模式;ARM异常处理过程;从异常处理程序的返回;从SWI和未定义指令异常处理程序返回;从FIQ和IRQ中断处理程序返回; 将返回地址压入栈中并在返回时将其弹出的处理程序入口和出口代码为:
SUB R14,R14,#4
STMFD SP!,{ reglist,R14 }
;...
LDMFD SP!,{ reglist,PC }^
对于发生在 Thumb 状态下的异常,处理程序返回指令 (SUBS PC,R14,#4) 改变了程序计数器,将其指向下一条要执行指令的地址。由于程序计数器的更新是在处理异常之前完成,下一条指令应在 (PC - 4) 。因此,处理器存储在R14_exc的值为PC 。;安装异常处理程序;Vector_Init_Block
LDR PC,Reset_Addr
LDR PC,Undefined_Addr
LDR PC,SWI_Addr
LDR PC,Prefetch_Addr
LDR PC,Abort_Addr
NOP ;Reserved vector
LDR PC,IRQ_Addr
LDR PC,FIQ_Addr
Reset_Addr DCD Start_Boot
Undefined_Addr DCD Undefined_Handler
SWI_Addr DCD SWI_Handler
Prefetch_Addr DCD Prefetch_Handler
Abort_Addr DCD Abort_Handler
DCD 0 ;Reserved vector
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler; 复位状态下,必须使ROM处在0x0位置。复位代码可将RAM映射到0x0位置 。
这样做之前,它需从ROM的某个区域将该向量(根据需要还有FIQ处理程序)复制到RAM中。
在此情况下,必须用一条LDR PC指令为复位处理程序确定地址,以便使复位向量代码能独立定位。
示例将上面示例给出的向量复制到了RAM中的向量表。
MOV R8, #0
ADR R9, Vector_Init_Block
LDMIA R9!,{R0-R7} ;Copy the vectors (8 words)
STMIA R8!,{R0-R7}
LDMIA R9!,{R0-R7} ;Copy the DCDed addresses
STMIA R8!,{R0-R7} ;(8 words again);从C安装处理程序
开发过程中有时必需从主应用程序直接将异常处理程序安装在向量中。结果,所需的指令编码必须被写到相应的向量地址中。这可由跳转和载入PC两种方法来转到该处理程序。
跳转方法:
1. 获取异常处理程序的地址。
2. 减去相应向量的地址。
3. 减去0x8以便预取。
4. 将结果右移两位给出一个字的偏移,而不是一个字节的偏移。
5. 测试其高八位为清除,确保结果仅为24位长(因为跳转的偏移被限制为此长度)。
6. 把它与0xEA000000(???转指令操作码)进行逻辑“或”运算,生成要放在向量中的值。;/* Updates contents of vector to contain branch instruction */
/* to reach ’routine’ from ’vector’. Function return value is */
/* original contents of vector.*/
/* NB: ’Routine’ must be within range of 32MB from ’vector’.*/
unsigned Install_Handler (unsigned routine, unsigned *vector)
{ unsigned vec, oldvec;
vec = ((routine - (unsigned)vector - 0x8)2);
if ((vec 0xFF000000)) /* diagnose the fault */
{
prinf (Installation of Handler failed);
exit (1);
}
vec = 0xEA000000 | vec;
oldvec = *vector;
*vector = vec;
return (oldvec);
}; 以下代码调用它来安装 IRQ 处理程序:
unsigned *irqvec = (unsig
显示全部