EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
第九章 ARM异常中断处理 ) ` C1 B/ m% r
9.1arm控制程序的执行流程 1、正常程序执行:每执行一条arm指令,PC值加4字节;每执行一条thumb指令,PC值加2字节。 2、跳转:B/BL/BLX,对于BLX,跳转到目标地址处执行,保存子程序的返回地址,根据目标地址的最低位可以将程序切换到thumb状态。 3、中断:系统先执行完当前指令,然后保存现场,之后跳转到异常中断处理程序。中断执行完后,恢复现场,程序返回到发生中断的指令的下一条指令处执行。 1 S( [2 d/ {% x: o3 m2 }
9.1.2异常中断向量表及优先级 中断向量地址 异常中断类型 异常中断模式 优先级(6级最低) 0x0 复位 特权模式(SVC) 1 0x4 未定义指令中止 未定义指令中止 6 0x8 软件中断(SWI) 特权模式(SVC) 6 0x0c 指令预取中止 中止模式 5 0x10 数据访问中止 中止模式 2 0x14 保留 0x18 外部中断请求(IRQ) 外部中断模式(IRQ) 4 0x1c 快速中断请求(FIQ) 快速中断模式(FIQ) 3 异常中断模式寄存器,除FIQ外,都只有R13、R14专用寄存器,使用这些寄存器时,必须用RN来定义这些名称。 R13_svc RN R13 : D3 d/ y, z* u1 `1 e) k
9.2异常中断响应过程 8 s- F* d- N' y/ l( Q: P
9.2.1 arm对异常中断的响应过程 1、保存处理器当前状态、中断屏蔽位以及各条件标志位 2、设置CPSR中相应位 3、保存返回地址到LR 4、将PC设置成中断向量地址 上述过程可以用伪指令描述为: R14_<exception_mode>=return link SPSR_<exception_mode>= CPSR CPSR[4:0]=exception mode number //运行于ARM状态 CPSR[5]=0 //禁止FIQ中断 CPSR[6]=1 //禁止IRQ中断 CPSR[7]=1 PC=exception vector address # I3 \! }: ]/ {2 B% c
1、响应复位异常中断 R14_svc=unpredictable value SPSR_svc=CPSR CPSR[4:0]=0b10011 //运行于ARM状态 CPSR[5]=0 //禁止FIQ中断 CPSR[6]=1 //禁止IRQ中断 CPSR[7]=1 if high vectors configured then PC=0xFFFF 0000 else PC=0x0000 0000
0 S/ o# E2 E9 l0 Y! o- y, n处理复位中断 STMFD SP!,{register,LR} ;... LDMFD SP!,{register,LR}^ ;^表示将SPSR_mode中的内容复制到CPSR
9 c. s# j5 V: T! ]1 d5 p) ^" K. n返回 MOV PC,LR
# q G, u) s% E. q% j- I+ Q
# T; u2 H" T# e5 V9 M2、响应未定义指令异常中断 R14_und=address of next instruction after the undefined instruction SPSR_und=CPSR CPSR[4:0]=0b11011 //运行于ARM状态 CPSR[5]=0 //禁止FIQ中断 CPSR[6]=1 //禁止IRQ中断 CPSR[7]=1 if high vectors configured then PC=0xFFFF 0004 else PC=0x0000 0004
# ^& z) z/ w) V! K) C5 A! i. V处理复位中断 SUBS LR,LR,#4 ;计算返回地址 STMFD SP!,{register,LR} ;保存使用到的寄存器 ;... LDMFD SP!,{register,LR}^ ;中断返回,^表示将SPSR_mode中的内容复制到CPSR ) o6 o% d: }& {) F/ p) Q7 }/ H( O
返回 MOVS PC,LR
. {+ z. M& y) a3、响应SWI异常中断 R14_svc=address of next instruction after the SWI instruction SPSR_svc=CPSR CPSR[4:0]=0b11011 //运行于ARM状态 CPSR[5]=0 //禁止FIQ中断 CPSR[6]=1 //禁止IRQ中断 CPSR[7]=1 if high vectors configured then PC=0xFFFF 0008 else PC=0x0000 0008
/ Z- O2 Q1 H) ^: V处理复位中断 SUBS LR,LR,#4 ;计算返回地址 STMFD SP!,{register,LR} ;保存使用到的寄存器 ;... LDMFD SP!,{register,LR}^ ;中断返回,^表示将SPSR_mode中的内容复制到CPSR
3 s$ g* n* E, i% b返回 MOVS PC,LR
; I8 i' f8 I- M5 d4、响应指令预取中止异常中断 R14_abt=address of the aborted instruction +4 SPSR_abt=CPSR CPSR[4:0]=0b10111 //运行于ARM状态 CPSR[5]=0 //CPSR[6]不变 //禁止IRQ中断 CPSR[7]=1 if high vectors configured then PC=0xFFFF 000C else PC=0x0000 000C $ K7 P q% M( U1 [- m! L
处理复位中断 SUBS LR,LR,#4 ;计算返回地址 STMFD SP!,{register,LR} ;保存使用到的寄存器 ;... LDMFD SP!,{register,LR}^ ;中断返回,^表示将SPSR_mode中的内容复制到CPSR
! o. M7 l8 e# U" O0 |* c! A返回 SUBS PC,LR,#4
3 l# H, d, p q- v5、响应数据访问中止异常中断 R14_abt=address of the aborted instruction +8 SPSR_abt=CPSR CPSR[4:0]=0b10111 //运行于ARM状态 CPSR[5]=0 // //CPSR[6]不变 //禁止IRQ中断 CPSR[7]=1 if high vectors configured then PC=0xFFFF 0010 else PC=0x0000 0010
1 D* O' S F3 p/ J! R8 e% F处理复位中断 SUBS LR,LR,#4 ;计算返回地址 STMFD SP!,{register,LR} ;保存使用到的寄存器 ;... LDMFD SP!,{register,LR}^ ;中断返回,^表示将SPSR_mode中的内容复制到CPSR 7 Q' A' t' h+ m& }: g
返回 SUBS PC,LR,#8
: ^: [9 ] I: c& T- g: H: @6、响应IRQ异常中断 R14_irq=address of next instruction to be executed +4 SPSR_irq=CPSR CPSR[4:0]=0b10010 //运行于ARM状态 CPSR[5]=0 // //CPSR[6]不变 //禁止IRQ中断 CPSR[7]=1 if high vectors configured then PC=0xFFFF 0018 else PC=0x0000 0018
' f8 T5 y8 `+ G6 `8 G$ `处理复位中断 SUBS LR,LR,#4 ;计算返回地址 STMFD SP!,{register,LR} ;保存使用到的寄存器 ;... LDMFD SP!,{register,LR}^ ;中断返回,^表示将SPSR_mode中的内容复制到CPSR 5 d5 s- F% j+ a7 x; t8 S6 E
返回 SUBS PC,LR,#4 3 ~" @, t3 Z3 r V! N& ?
7、响应FIQ异常中断 R14_fiq=address of next instruction to be executed +4 SPSR_fiq=CPSR CPSR[4:0]=0b10001 //运行于ARM状态 CPSR[5]=0 //禁止FIQ中断 CPSR[6]=1 //禁止IRQ中断 CPSR[7]=1 if high vectors configured then PC=0xFFFF 001C else PC=0x0000 001C 1 D# x2 W- t( P( ]% S3 \0 J" t
处理复位中断 SUBS LR,LR,#4 ;计算返回地址 STMFD SP!,{register,LR} ;保存使用到的寄存器 ;... LDMFD SP!,{register,LR}^ ;中断返回,^表示将SPSR_mode中的内容复制到CPSR 6 ]$ b+ _* `) V! E: a+ Z0 E
返回 SUBS PC,LR,#4 " ^- { w- K6 ~% @6 _6 |
9.3 中断注册 两种方法:1、使用跳转指令将中断处理程序注册到中断向量表。简单,但是只能在32MB空间范围内跳转 2、使用LDR指令。分两步:先将中断处理程序的绝对地址存放在距离向量表4KB范围内的存储单元中,再用LDR将该单元内容读取到PC中 % O o1 y$ J# G( w0 o. F% c# Z
9.3.1系统复位是注册异常中断处理程序 又分为2中情况: 1、起始地址0x0处为ROM 2、起始地址0x0处为RAM
4 B9 C$ a4 t3 G: D0 @起始地址0x0为ROM 使用跳转指令 Vector_Init_Block BL Reset_Handler BL Undefined_Handler BL SWI_Handler BL Prefetch_Handler BL Abort_Handler NOP BL IRQ_Handler BL FIQ_Handler
2 d& k7 [% r8 z- u6 d$ x3 v使用LDR指令 Vector_Init_Block LDR PC, Reset_Addr LDR PC, Undefined_Addr LDR PC, SWI_Addr LDR PC, Prefetch_Addr LDR PC, Abort_Addr NOP LDR PC, IRQ_Addr LDR PC, FIQ_Addr
" Y7 l1 M( C9 R- a$ z* t' ~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 NOP IRQ_Addr DCD IRQ_Handler FIQ_Addr DCD FIQ_Handler
& r4 U1 T. |6 k6 E2地址0x0为RAM 中断向量表必须使用数据读取指令直接向PC中赋值的形式。而且必须使用下面的代码把中断向量表从ROM中复制到RAM的地址0x0处。 MOV R8, #0 ADR R9,Vector_Init_Block ;复制中断向量表(8字节) LDMIA R9!,{R0-R7} STMIA R8!,{R0-R7} ;复制中断处理函数地址表(8字节) LDMIA R9!,{R0-R7} STMIA R8!,{R0-R7}
) f+ ^- \% w4 q+ u9 m" N! S9.3.2 在C程序中注册异常中断处理程序 中断向量表中使用跳转指令 1、读取中断处理程序的地址 2、从上一步得到的地址中减去异常中断对应的中断向量地址 3、从上一步得到的地址中减去8,以允许指令预取 4、将上一步得到的地址右移2位,得到以字为单位的偏移量 5、确保上一步得到的地址值高8位为0,因为跳转指令只允许24位的偏移量 6、将上一步得到的地址与数据0xea00 0000作逻辑或,从而得到将要写的中断向量表中的跳转指令的编码 unsigned Install_Handler (unsigned routine ,unsigned *vector) //vector中断向量表,routine中断处理程序 //程序返回原来的中断向量 { unsigned vec,oldvec; vec=((routine-(unsigned)vector-0x8)>>2); if(vec&0xff000000) { printf("Installation of Handler failed!"); exit(1); } vec=0xea00 0000|vec; oldvec=*vector; *vector=vec; return oldvec; } //下面语句调用中断注册函数 unsigned *irqvec=(unsigned *)0x18; Install_Handler ((unsigned)IRQHandler,irqvec); $ I* \3 {& m. M" Q9 m4 s
中断向量表使用数据读取指令注册 1、读取中断处理程序的地址 2、从上一步得到的地址中减去异常中断对应的中断向量地址 3、从上一步得到的地址中减去8,以允许指令预取 4、将上一步得到的地址与数据0xe59f f000作逻辑或,从而得到将要写的中断向量表中的跳转指令的编码 unsigned Install_Handler (unsigned location ,unsigned *vector) //vector中断向量表,location目标地址 //程序返回原来的中断向量 { unsigned vec,oldvec; vec=(location-(unsigned)vector-0x8) |0xe59ff000; oldvec=*vector; *vector=vec; return oldvec; } //下面语句调用中断注册函数 unsigned *irqvec=(unsigned *)0x18; Install_Handler ((unsigned)IRQHandler,irqvec); 5 T! _# [2 Z& `) L; u9 V2 J5 L+ b) J' a
|