arm9-ucos中断过程分析
来源:互联网 发布:淘宝店铺推广多少钱 编辑:程序博客网 时间:2024/04/28 23:05
步骤1:发生中断后,跳到地址0的中断向量表;b HandlerIRQ ;handler for IRQ interrupt
步骤2:然后跳到,中断函数HandlerIRQ ,这个函数就做了并且只是了一件事取出全局变量HandleIRQ 地址上的函数并且使pc跳到该函数,
//堆栈是满降方式就是说 ,sp指向满的地方,当压栈时,先sp自减4然后存数据到sp所指地址,这里仅仅是取出数据到pc没其他操作
具体实现代码如下: MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does''t push because it return to original address)
ldr r0,=$HandleLabel;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
步骤3:因为在系统复位的时候, 全局变量HandleIRQ处被安放了汇编函数OS_CPU_IRQ_ISR,
; Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
;ldr r1,=IsrIRQ ;if there isn''t 'subs pc,lr,#4' at 0x18, 0x1c
ldr r1, =OS_CPU_IRQ_ISR ;modify by txf, for ucos
str r1,[r0]
OS_CPU_IRQ_ISR是一个汇编函数定义如下:
//该函数就是从cpu寄存器里面得到中断偏移,然后根据偏移,和标号IRQIsrVect(也就是定义在内存地址_ISR_STARTADDRESS上的HandleEINT0地址)
相加得到具体中断处理函数的地址,然后从这个地址取出中断函数(这个中断函数就是在c语言中用户自己放上去的,比如pISR_TIMER0= (uint32) OSTickISR;pISR_TIMER0就是定义在地址_ISR_STARTADDRESS上的变量),然后调用他,
最后OS_CPU_IRQ_ISR返回
具体实现代码:
OS_CPU_IRQ_ISR STMFD SP!, {R1-R3}; We will use R1-R3 as temporary registers;----------------------------------------------------------------------------; R1--SP;R2--PC ; R3--SPSR;------------------------------------------------------------------------MOV R1, SPADD SP, SP, #12 ;Adjust IRQ stack pointerSUB R2, LR, #4 ;Adjust PC for return address to taskMRS R3, SPSR; Copy SPSR (Task CPSR) MSR CPSR_cxsf, #SVCMODE|NOINT ;Change to SVC mode; SAVE TASK''S CONTEXT ONTO OLD TASK''S STACKSTMFD SP!, {R2}; Push task''s PC STMFD SP!, {R4-R12, LR}; Push task''s LR,R12-R4LDMFD R1!, {R4-R6}; Load Task''s R1-R3 from IRQ stack STMFD SP!, {R4-R6}; Push Task''s R1-R3 to SVC stackSTMFD SP!, {R0} ; Push Task''s R0 to SVC stackSTMFD SP!, {R3}; Push task''s CPSRLDR R0,=OSIntNesting ;OSIntNesting++LDRB R1,[R0]ADD R1,R1,#1STRB R1,[R0] CMP R1,#1 ;if(OSIntNesting==1){BNE %F1 LDR R4,=OSTCBCur ;OSTCBHighRdy->OSTCBStkPtr=SP;LDR R5,[R4]STR SP,[R5] ;}1MSR CPSR_c,#IRQMODE|NOINT ;Change to IRQ mode to use IRQ stack to handle interruptLDR R0, =INTOFFSET LDR R0, [R0] LDR R1, IRQIsrVect MOV LR, PC ; Save LR befor jump to the C function we need return back LDR PC, [R1, R0, LSL #2] ; Call OS_CPU_IRQ_ISR_handler(); 这里用的是ldr指令所以用户的终端函数OSTickISR要外层要加一个汇编函数. MSRCPSR_c,#SVCMODE|NOINT ;Change to SVC mode BL OSIntExit ;Call OSIntExit LDMFD SP!,{R4} ;POP the task''s CPSR MSRSPSR_cxsf,R4 LDMFD SP!,{R0-R12,LR,PC}^ ;POP new Task''s context
注意2:全局变量HandleIRQ的定义如下:
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
OS_CPU_IRQ_ISR 函数分析:
首先把r1-r3保存到sp,然后
OS_CPU_IRQ_ISR
STMFD SP!, {R1-R3} ; We will use R1-R3 as temporary registers
;----------------------------------------------------------------------------
; R1--SP
; R2--PC
; R3--SPSR
;------------------------------------------------------------------------
MOV R1, SP
ADD SP, SP, #12 ;Adjust IRQ stack pointer
SUB R2, LR, #4 ;Adjust PC for return address to task
MRS R3, SPSR ; Copy SPSR (Task CPSR)
MSR CPSR_cxsf, #SVCMODE|NOINT ;Change to SVC mode
; SAVE TASK''S CONTEXT ONTO OLD TASK''S STACK
STMFD SP!, {R2} ; Push task''s PC
STMFD SP!, {R4-R12, LR} ; Push task''s LR,R12-R4
LDMFD R1!, {R4-R6} ; Load Task''s R1-R3 from IRQ stack
STMFD SP!, {R4-R6} ; Push Task''s R1-R3 to SVC stack
STMFD SP!, {R0} ; Push Task''s R0 to SVC stack
STMFD SP!, {R3} ; Push task''s CPSR
LDR R0,=OSIntNesting ;OSIntNesting++
LDRB R1,[R0]
ADD R1,R1,#1
STRB R1,[R0]
CMP R1,#1 ;if(OSIntNesting==1){
BNE %F1
LDR R4,=OSTCBCur ;OSTCBHighRdy->OSTCBStkPtr=SP;
LDR R5,[R4]
STR SP,[R5] ;}
1
MSR CPSR_c,#IRQMODE|NOINT ;Change to IRQ mode to use IRQ stack to handle interrupt
LDR R0, =INTOFFSET
LDR R0, [R0]
LDR R1, IRQIsrVect
MOV LR, PC ; Save LR befor jump to the C function we need return back
LDR PC, [R1, R0, LSL #2] ; Call OS_CPU_IRQ_ISR_handler();
MSR CPSR_c,#SVCMODE|NOINT ;Change to SVC mode
BL OSIntExit ;Call OSIntExit
LDMFD SP!,{R4} ;POP the task''s CPSR
MSR SPSR_cxsf,R4
LDMFD SP!,{R0-R12,LR,PC}^ ;POP new Task''s context
IRQIsrVect DCD HandleEINT0
- arm9-ucos中断过程分析
- arm9-裸机中断过程分析(2012-02-07 11:12)
- arm9 ucos 移植
- arm9 norflash与nandflash启动过程分析
- arm9 norflash与nandflash启动过程分析
- arm9 norflash与nandflash启动过程分析
- arm9-rtos的中断汇编代码分析helper2416-rawos
- ucos在s3c2410上运行过程整体剖析之基础知识-与UCOS运行有关的ARM9芯片知识
- ucos在s3c2410上运行过程整体剖析之基础知识-与UCOS运行有关的ARM9芯片知识--续
- ucos在s3c2410上运行过程整体剖析之基础知识(3)-与UCOS运行有关的ARM9芯片知识 .
- Arm中断过程分析
- ucOS-II基于ARM920T的中断处理过程
- 一起来学嵌入式之ARM9中断机制-中断信号处理过程及实例
- ARM9中断与PC
- ARM9中断控制器
- ARM9---中断篇
- ARM9串口中断
- ARM9---中断篇
- SVN版本冲突中 Files 的值“ < < < < < < < .mine”无效路径中具有非法字符
- 第十三周实验报告(二)
- 如何在Hadoop集群运行JNI程序
- 强制进行make方法
- 类似百度搜索时的模糊查询
- arm9-ucos中断过程分析
- 基础测试用例的作用
- 第十三周实验报告(三)
- 从myeclipse导入eclipse导致不能识别为web项目(java项目转为web项目)
- 透明滚动条 HTML
- occ 关键字 new
- ORA-01950:no privileges on tablespace 'USERS'
- OpenCV直方图介绍
- 常用js大全