ARM汇编嵌套中断处理
来源:互联网 发布:宽带网络那家好 编辑:程序博客网 时间:2024/04/28 13:56
参考书籍:《ARM嵌入式系统开发---软件设计与优化》、《一步步写嵌入式操作系统--ARM编程的方法与实践》
嵌套中断考虑了当前调用中断处理执行过程中又发送中断的情形。使用类似函数递归调用的栈帧概念来将上下文压入堆栈。
具体参考《ARM嵌入式系统开发》第九章9.3.2部分和《一步步》的第五章5.4部分,前者比较通用完整。描速的都是在IRQ模式下不能简单打开中断,而是转换到SVC模式下保存上下文。
下面核心源代码是摘抄于《ARM嵌入式系统开发》的配套源码:
;/*; * ____________________________________________________________________; * ; * Copyright (c) 2004, Andrew N. Sloss, Chris Wright and Dominic Symes; * All rights reserved.; * ____________________________________________________________________; * ; * NON-COMMERCIAL USE License; * ; * Redistribution and use in source and binary forms, with or without ; * modification, are permitted provided that the following conditions ; * are met: ; * ; * 1. For NON-COMMERCIAL USE only.; * ; * 2. Redistributions of source code must retain the above copyright ; * notice, this list of conditions and the following disclaimer. ; * ; * 3. Redistributions in binary form must reproduce the above ; * copyright notice, this list of conditions and the following ; * disclaimer in the documentation and/or other materials provided ; * with the distribution. ; * ; * 4. All advertising materials mentioning features or use of this ; * software must display the following acknowledgement:; * ; * This product includes software developed by Andrew N. Sloss,; * Chris Wright and Dominic Symes. ; * ; * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY ; * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ; * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE ; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ; * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ; * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ; * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ; * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ; * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ; * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY ; * OF SUCH DAMAGE. ; * ; * If you have questions about this license or would like a different; * license please email :; * ; * andrew@sloss.net; * ; * ; */;/***********************************************************************; *; * Module : nih9_9.s; * Descriptions : Nested Interrupt Handler; * Example : 9.9; * OS : generic; * Platform : generic; * History :; *; * 31th December 2003; * - added header; *; ***********************************************************************/ EXPORT nestedInterruptHandlerMaskmd EQU 0x1f ; processor mode maskSVC32md EQU 0x13 ; SVC modeI_Bit EQU 0x80 ; IRQ bit FRAME_R0 EQU 0x00FRAME_R1 EQU FRAME_R0+4FRAME_R2 EQU FRAME_R1+4FRAME_R3 EQU FRAME_R2+4FRAME_R4 EQU FRAME_R3+4FRAME_R5 EQU FRAME_R4+4FRAME_R6 EQU FRAME_R5+4FRAME_R7 EQU FRAME_R6+4FRAME_R8 EQU FRAME_R7+4FRAME_R9 EQU FRAME_R8+4FRAME_R10 EQU FRAME_R9+4FRAME_R11 EQU FRAME_R10+4FRAME_R12 EQU FRAME_R11+4FRAME_PSR EQU FRAME_R12+4FRAME_LR EQU FRAME_PSR+4FRAME_PC EQU FRAME_LR+4FRAME_SIZE EQU FRAME_PC+4AREA nih9_9,CODE,readonlynestedInterruptHandler ; instruction state : comment SUB r14,r14,#4 ; 2 : STMDB r13!,{r0-r3,r12,r14} ; 2 : save context ; <insert code here> BL read_RescheduleFlag ; 3 : more processing CMP r0,#0 ; 3 : if processing? LDMNEIA r13!,{r0-r3,r12,pc}^ ; 4 : then 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 SVC mode SUB r13,r13,#FRAME_SIZE-FRAME_R4 ; 7 : make stack space STMIA r13,{r4-r11} ; 7 : save r4-r11 LDMIA r0,{r4-r9} ; 7 : r4-r9 IRQ stack BIC r1,r1,#I_Bit ; 8 : MSR CPSR_c,r1 ; 8 : enable int 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 ; <insert code here> LDMIA r13!,{r0-r12,r14} ; 11 : restore context MSR SPSR_cxsf,r14 ; 11 : restore SPSR LDMIA r13!,{r14,pc}^ ; 11 : returnread_RescheduleFlag ; <implement your own reschedule flag code here> MOV r0,#0 ; more processing MOV pc,r14 ; return END
将irq和svc两种模式的堆栈图画出来观看的话,理解起来比较直观。因为我是初学,刚开始没能理解其中堆栈操作,原因是:
1.忘记了r0-r12,cpsr是irq和svc共用的堆栈,r13(sp),r14(lr)和spsr是不相同的。
2.对堆栈向下生长不够深刻,刚开始还记得后来有弄反了,导致理解不了,还一度认为书上有错。
3.对ARM的堆栈操作指令和多寄存器传送指令比较生疏,需要查表对照,一步一步得走
另外我觉得书上描速的完成一个栈帧从高地址往低地址的情况好像反了,感觉应该是lr_irq,r14_svc,spsr_irq,r12-r0的顺序。
下面在mini2440板子上實現嵌套中斷:使用了LED PB8(LED4)和PB7(LED3)低電平亮,外部中斷8和19,對應按鍵是K1和K6.
.equ NOINT, 0xc0 .equ I_Bit, 0x80 .equ SVC_MOD, 0x13.equ IRQ_MOD, 0x12.equ WTCON, 0x53000000.equ GPBCON, 0x56000010.equ GPBDAT, 0x56000014.equ GPBUP, 0x56000018.equ GPGCON, 0x56000060.equ EINTMASK, 0x560000a4 .equ EXTINT1, 0x5600008c .equ EXTINT2, 0x56000090.equ EINTPEND, 0x560000a8 .equ INTMSK, 0x4A000008 .equ SRCPND, 0X4A000000 .equ INTPND, 0X4A000010 .equ SVC_Stack, 4096.equ IRQ_Stack, 2048@栈帧定义.equ FRAME_R0, 0x00.equ FRAME_R1, FRAME_R0+4.equ FRAME_R2, FRAME_R1+4.equ FRAME_R3, FRAME_R2+4.equ FRAME_R4, FRAME_R3+4.equ FRAME_R5, FRAME_R4+4.equ FRAME_R6, FRAME_R5+4.equ FRAME_R7, FRAME_R6+4.equ FRAME_R8, FRAME_R7+4.equ FRAME_R9, FRAME_R8+4.equ FRAME_R10, FRAME_R9+4.equ FRAME_R11, FRAME_R10+4.equ FRAME_R12, FRAME_R11+4.equ FRAME_PSR, FRAME_R12+4.equ FRAME_LR, FRAME_PSR+4.equ FRAME_PC, FRAME_LR+4.equ FRAME_SIZE, FRAME_PC+4.text.code 32.global _start_start: b resetldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldrpc, _data_abort ldr pc, _not_used ldr pc, _irq ldr pc, _fiq_undefined_instruction: .word undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq.balignl 16,0xdeadbeefreset:ldr r0,=WTCONmov r1,#0x0str r1,[r0] @关看门狗msr cpsr_c,#(IRQ_MOD|NOINT)ldr sp,=IRQ_Stack msr cpsr_c,#(SVC_MOD|NOINT) ldr sp,=SVC_Stackldr r0,=GPBCONldr r1,=0x14000str r1,[r0] @PB8,7输出ldr r0,=GPBDATmov r1,#0x180str r1,[r0] @8、7高电平 ldr r0,=GPGCONldr r1,=0x800002str r1,[r0] @使能外部中断8,外部中断19ldr r0,=EXTINT1mov r1,#0x03str r1,[r0] @外部8下降沿触发ldr r0,=EXTINT2ldr r1,=0x3000str r1,[r0] @外部19下降沿触发ldr r0, =EINTPEND ldr r1,=0x00fffff0str r1,[r0]@ 清EINTPEND,写1清零ldr r0,=EINTMASKldr r1,=0xfff7feffstr r1,[r0] @使能外部中断8、19,0为使能ldr r0, =SRCPND ldr r1,=0xffffffffstr r1,[r0]@ 清SRCPND,写1清零ldr r0, =INTPND ldr r1,=0xffffffff str r1,[r0]@ 清INTPND,写1清零ldr r0,=INTMSKldr r1,=0xffffffdfstr r1,[r0] @使能外部中断EINT8-23mrs r1, cpsr bic r1, r1, #I_Bit msr cpsr_c, r1 @开全局IRQ中断loop:b loopirq_server1:stmfd sp!,{lr} ldr r0,=GPBDATldr r1,[r0]bic r2,r1,#0x100str r2,[r0]bl delay1orr r2,r1,#0x100str r2,[r0]@bl delay1ldmfd sp!,{lr} mov pc,lrirq_server2:stmfd sp!,{lr} ldr r0,=GPBDATldr r1,[r0]bic r2,r1,#0x80str r2,[r0]bl delay2orr r2,r1,#0x80str r2,[r0]@bl delay2ldmfd sp!,{lr} mov pc,lrdelay1: ldr r12,=0x5ffffffdelay1loop: sub r12,r12,#1 cmp r12,#0x0 bne delay1loop mov pc,lrdelay2: ldr r3,=0x5ffffff delay2loop: sub r3,r3,#1 cmp r3,#0x0 bne delay2loop mov pc,lrundefined_instruction: nop software_interrupt: nop prefetch_abort: nop data_abort: nop not_used: nop irq: sub r14,r14,#4 stmdb r13!,{r0-r3,r12,r14} @ save contextldr r0, =EINTPENDldr r10,[r0]ldr r11,=0x80100tst r10,r11 @判断是否为EINT8、19,r10记录哪个外部中断ldr r0, =EINTPEND ldr r1,[r0] @ldr r1,=0x100str r1,[r0] @清EINTPENDldr r0, =SRCPND ldr r1,[r0] @ldr r1,=0x20str r1,[r0] @清SRCPNDldr r0, =INTPND ldr r1,[r0] @ldr r1,=0x20str r1,[r0] @清INTPNDldmeqfd r13!,{r0-r3,r12,pc}^mrs r2,SPSR @ copy SPSR_irqmov r0,r13 @ copy r13_irqadd r13,r13,#6*4 @ reset stack msr cpsr_c,#(SVC_MOD|NOINT) @ change SVC modesub r13,r13,#FRAME_SIZE-FRAME_R4 @ make stack space stmia r13,{r4-r11} @ save r4-r11ldmia r0,{r4-r9} @ r4-r9 IRQ stack mrs r1, cpsr bic r1, r1, #I_Bitmsr cpsr_c, r1 @开全局IRQ中断stmdb r13!,{r4-r7} @ save r4-r7 SVCstr r2,[r13,#FRAME_PSR] @ save PSRstr r8,[r13,#FRAME_R12] @ save r12str r9,[r13,#FRAME_PC] @ save pc str r14,[r13,#FRAME_LR] @ save lrldr r11,=0x80000cmp r10,r11bleq irq_server1blne irq_server2ldmia r13!,{r0-r12,r14} @ restore contextmsr SPSR_cxsf,r14 @ restore SPSRldmia r13!,{r14,pc}^ @ returnfiq: nop
可以看到中斷的嵌套,但是按下K6多次後會有問題,譬如LED4一直暗,或一直亮,再按那兩個中斷按鍵也沒反應。JLink調試發現按一次按鍵,中斷重入好幾次,大概是沒有去抖動導致,連續按久了,堆棧溢出?同時還會跑到“ldr pc, _undefined_instruction “這一句上,跑飛了?問題的原因還有待確認!
0 0
- ARM汇编嵌套中断处理
- GNU ARM汇编--(五)中断汇编之嵌套中断处理
- GNU ARM汇编--(五)中断汇编之嵌套中断处理
- GNU ARM汇编--(五)中断汇编之嵌套中断处理
- GNU ARM汇编--(四)中断汇编之非嵌套中断处理
- GNU ARM汇编--(四)中断汇编之非嵌套中断处理
- GNU ARM汇编--(四)中断汇编之非嵌套中断处理
- ARM中断处理及状态机嵌套实现
- 谈谈ARM中断嵌套
- ARM汇编外部中断
- ARM中断原理, 中断嵌套的误解
- ARM中断原理, 中断嵌套的误解
- 理解ARM中断原理以及中断嵌套
- 汇编~~~~~~~~~中断处理程序
- 汇编中断处理
- ARM中断处理分析
- ARM 中断处理过程
- ARM中的中断处理
- 输了你我输了全部
- 二十四、C++程序设计必知:多文件结构和编译预处理命令
- S2E的安装 ubuntu12.04 64bit
- 大话设计模式之适配器模式
- 黑马程序员——C语言(scanf函数、基本运算、流程控制)总结
- ARM汇编嵌套中断处理
- JSP:请求数据和请求本身的一些信息
- 常用数据库的驱动类/URL/默认端口
- 天声人語 20150426
- ZOJ 3870 Team Formation(异或运算)
- Pig
- HDU1358 Period【KMP】
- 日经春秋 20150426
- 初学Linux中进程调度与进程切换过程