关于ARM中断处理的有关问题-《ARM嵌入式系统开发-软件设计与优化》第九章中疑问
关于ARM中断处理的问题----《ARM嵌入式系统开发-软件设计与优化》第九章中疑问
各位过年好哦~
呵呵,小弟这里有点疑惑相同大家讨论讨论~,这个问题是《ARM嵌入式系统开发-软件设计与优化》一书中的见下:
第九章-中断处理
9.3.2嵌套中断
在这一节中,描述了如何处理嵌套式的中断(不能单纯的在IRQ模式下打开中断允许位),作者介绍是从IRQ模式切换到SVC模式中去处理中断,并且一如了Stack Frame的用法,书中也有相关的一点代码,对这段代码有点疑问:
为什么要在Frame Stack未创建完成时打开中断呢?此时r4-r7,r2,r8,r9,r14都还没保存,如果有中断发生,岂不是会覆盖这么寄存器(重要的是会覆盖r9)导致中断服务程序不能正常返回。
各位有何高见~
------解决方案--------------------
1,IRQ模式的r4-r9和SVC模式的r4-r9是同一组寄存器。
2,LDMIA r0,{r4-r9} ; 7 : restore r4-r9
这句之前是:STMIA r13,{r4-r11} ; 7 : save r4-r11
这一句把上一次的r4-r9保存了。
之后,LDMIA r13!,{r0-r12,r14} ; 11 : restore context
这一句又把r4-r9恢复了。
你自己画个SVC模式的栈空间变化图仔细想想。
各位过年好哦~
呵呵,小弟这里有点疑惑相同大家讨论讨论~,这个问题是《ARM嵌入式系统开发-软件设计与优化》一书中的见下:
第九章-中断处理
9.3.2嵌套中断
在这一节中,描述了如何处理嵌套式的中断(不能单纯的在IRQ模式下打开中断允许位),作者介绍是从IRQ模式切换到SVC模式中去处理中断,并且一如了Stack Frame的用法,书中也有相关的一点代码,对这段代码有点疑问:
- Assembly code
Maskmd EQU 0x1f ; processor mode mask SVC32md EQU 0x13 ; SVC mode I_Bit EQU 0x80 ; IRQ bit FRAME_R0 EQU 0x00 FRAME_R1 EQU FRAME_R0+4 FRAME_R2 EQU FRAME_R1+4 FRAME_R3 EQU FRAME_R2+4 FRAME_R4 EQU FRAME_R3+4 FRAME_R5 EQU FRAME_R4+4 FRAME_R6 EQU FRAME_R5+4 FRAME_R7 EQU FRAME_R6+4 FRAME_R8 EQU FRAME_R7+4 FRAME_R9 EQU FRAME_R8+4 FRAME_R10 EQU FRAME_R9+4 FRAME_R11 EQU FRAME_R10+4 FRAME_R12 EQU FRAME_R11+4 FRAME_PSR EQU FRAME_R12+4 FRAME_LR EQU FRAME_PSR+4 FRAME_PC EQU FRAME_LR+4 FRAME_SIZE EQU FRAME_PC+4 IRQ_Entry ; instruction state : comment SUB r14,r14,#4 ; 2 : STMDB r13!,{r0-r3,r12,r14} ; 2 : save context <service interrupt> BL read_RescheduleFlag ; 3 : more processing CMP r0,#0 ; 3 : if processing? LDMNEIA r13!,{r0-r3,r12,pc}ˆ ; 4 : else return MRS r2,spsr ; 5 : copy spsr_irq MOV r0,r13 ; 5 : copy r13_irq ADD r13,r13,#6*4 ; 5 : reset stack MRS r1,cpsr ; 6 : copy cpsr BIC r1,r1,#Maskmd ; 6 : ORR r1,r1,#SVC32md ; 6 : MSR cpsr_c,r1 ; 6 : change to SVC SUB r13,r13,#FRAME_SIZE-FRAME_R4 ; 7 : make space STMIA r13,{r4-r11} ; 7 : save r4-r11 LDMIA r0,{r4-r9} ; 7 : restore r4-r9 BIC r1,r1,#I_Bit ; 8 : MSR cpsr_c,r1 ; 8 : enable IRA STMDB r13!,{r4-r7} ; 9 : save r4-r7 SVC STR r2,[r13,#FRAME_PSR] ; 9 : save PSR STR r8,[r13,#FRAME_R12] ; 9 : save r12 STR r9,[r13,#FRAME_PC] ; 9 : save pc STR r14,[r13,#FRAME_LR] ; 9 : save lr <complete interrupt service routine> LDMIA r13!,{r0-r12,r14} ; 11 : restore context MSR spsr_cxsf,r14 ; 11 : restore spsr LDMIA r13!,{r14,pc}ˆ ; 11 : return
为什么要在Frame Stack未创建完成时打开中断呢?此时r4-r7,r2,r8,r9,r14都还没保存,如果有中断发生,岂不是会覆盖这么寄存器(重要的是会覆盖r9)导致中断服务程序不能正常返回。
各位有何高见~
------解决方案--------------------
1,IRQ模式的r4-r9和SVC模式的r4-r9是同一组寄存器。
2,LDMIA r0,{r4-r9} ; 7 : restore r4-r9
这句之前是:STMIA r13,{r4-r11} ; 7 : save r4-r11
这一句把上一次的r4-r9保存了。
之后,LDMIA r13!,{r0-r12,r14} ; 11 : restore context
这一句又把r4-r9恢复了。
你自己画个SVC模式的栈空间变化图仔细想想。