打印

UCOS for lpc2000 arm 移植中断入口代码分析

[复制链接]
1948|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
machunshui|  楼主 | 2009-10-13 09:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 machunshui 于 2009-10-13 09:23 编辑

UCOS for lpc2000 arm 移植中断入口代码分析


arm由于有多种运行模式,导致ucos在arm上移植时,中断入口处理比别的MCU复杂不少,现试作以下分析。


这是一段基于IAR的ucos 在lpc2000 arm上的移植。

;*********************************************************************************************************
;                                      IRQ Interrupt Service Routine
;*********************************************************************************************************

        RSEG CODE:CODE:NOROOT(2)
        CODE32

OS_CPU_IRQ_ISR

        STMFD   SP!, {R1-R3}                   ; 下面要用到r1,r2,r3,先入中断模式堆栈保护                     
        
        MOV     R1, SP                         ; 中断模式SP--->r1
        
        ADD     SP, SP,#12                     ; 调整中断模式SP,使之指向r1,r2,r3入栈前的位置
        
        SUB     R2, LR,#4                      ; 调整中断返回地址

        MRS     R3, SPSR                       ; 中断模式spsr--->r3,中断模式spsr即发生中断前的任务代码的cpsr
        
        MSR     CPSR_c, #(NO_INT | SVC32_MODE) ; 转换到管理模式(即任务代码的运行模式)

                                               ; SAVE TASK'S CONTEXT ONTO TASK'S STACK
        STMFD   SP!, {R2}                      ;   中断返回地址入管理模式堆栈
        STMFD   SP!, {LR}                      ;    任务的LR入管理模式堆栈
        STMFD   SP!, {R4-R12}                  ;    R4-R12入管理模式堆栈
        
        LDMFD   R1!, {R4-R6}                   ;    由中断模式的堆栈弹出先前保存的r1,r2,r3
        STMFD   SP!, {R4-R6}            ;   入管理模式堆栈
        STMFD   SP!, {R0}                      ;    r0入管理模式堆栈
        STMFD   SP!, {R3}                      ;    中断模式spsr入管理模式堆栈,中断模式spsr即即发生中断前的任务代码的cpsr
               
                                               ;
        LDR     R0, ??OS_IntNesting            ; OSIntNesting++;
        LDRB    R1, [R0]
        ADD     R1, R1,#1
        STRB    R1, [R0]

        CMP     R1, #1                         ; if (OSIntNesting == 1) {
        BNE     OS_CPU_IRQ_ISR_1

        LDR     R4, ??OS_TCBCur                ;    非嵌套中断, OSTCBCur->OSTCBStkPtr = SP
        LDR     R5, [R4]
        STR     SP, [R5]                       ; }

OS_CPU_IRQ_ISR_1
        MSR     CPSR_c, #(NO_INT | IRQ32_MODE) ; 切换到IRQ模式
        
        LDR     R0, ??OS_CPU_IRQ_ISR_Handler   ; 调用用户中断处理
        MOV     LR, PC
        BX      R0            
        
        MSR     CPSR_c, #(NO_INT | SVC32_MODE) ; 切换到管理模式
        
        LDR     R0, ??OS_IntExit               ; OSIntExit(),任务切换代码在其中
        MOV     LR, PC
        BX      R0            
        
                                               ; 返回到新任务
        LDMFD   SP!, {R4}                       ; 任务代码的cpsr出管理模式堆栈
        MSR     SPSR_cxsf, R4            ;存入当前管理模式的SPSR
        
        LDMFD   SP!, {R0-R12,LR,PC}^           ;    任务环境出管理模式堆栈,中断退出,注意:指令最后的^ ,在出出栈列表里面有PC的时候表示,把SPSR复制到CPSR

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

153

主题

3224

帖子

4

粉丝