3096|0

1

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

基于IAR的UCOS程序问题? [复制链接]

 这几天在弄UCOS ii的程序,是基于IAR软件的。其中有个地方不是很明白,在程序的开始,堆栈好各堆栈后进入的系统模式(sys),也就是说任务在系统模式下运行。但中断(irq)来了后进入IRQ模式执行中断的汇编代码(os_cpu_a.asm),可是在刚进入IRQ后就切换到了管理模式(SVC),之后调用中断的C语言部分。问题是为什么又进入了SVC模式呢?那这样的的话IRQ的任务堆栈,SVC的堆栈大小不是很小就可以了吗?

OS_CPU_ARM_ExceptIrqHndlr
    SUB     LR, LR, #4                                          ;
    STMFD   SP!, {R0-R3}                                        ;压栈工作寄存器

    MOV     R0, #OS_CPU_ARM_EXCEPT_IRQ                          ; Set exception ID to OS_CPU_ARM_EXCEPT_IRQ.
    MRS     R1, SPSR                                            ;
    MOV     R2, LR                                              ; 保存连接寄存器
    MOV     R3, SP                                              ; 保存堆栈指针

                                                                ; Change to SVC mode & disable interruptions.
    MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) ;切换到SVC模式
                                                 ;为什么要切换到SVC模式 有的说是为了中断的嵌套?
                                                   ; SAVE CONTEXT ONTO SVC STACK:
    STMFD   SP!, {R2}                              ;   Push task's PC,
    STMFD   SP!, {LR}                              ;   Push task's LR,
    STMFD   SP!, {R4-R12}                          ;   Push task's R12-R4,
    LDMFD   R3!, {R5-R8}                           ;   Move task's R3-R0 from exception stack to task's stack.
    STMFD   SP!, {R5-R8}
    STMFD   SP!, {R1}                                           ;   Push task's CPSR (i.e. exception SPSR).
                                                               
    LDR     R3, =OSRunning                      ; if (OSRunning == 1)                     
    LDRB    R4, [R3] ;
    CMP     R4, #1
    BNE     OS_CPU_ARM_IRQHndlr_BreakNothing

                                                                ; HANDLE NESTING COUNTER:
    LDR     R3, =OSIntNesting                                   ;   OSIntNesting++;
    LDRB    R4, [R3]
    ADD     R4, R4, #1
    STRB    R4, [R3]

    CMP     R4, #1                                              ; if (OSIntNesting == 1)
    BNE     OS_CPU_ARM_IRQHndlr_BreakIRQ

;********************************************************************************************************
;                                      IRQ HANDLER: TASK INTERRUPTED
;
; Register Usage:  R0     Exception Type
;                  R1
;                  R2
;                  R3
;********************************************************************************************************

OS_CPU_ARM_IRQHndlr_BreakTask
    LDR     R3, =OSTCBCur                                       ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R4, [R3]
    STR     SP, [R4]

    LDR     R3, =OS_CPU_ExceptStkBase                           ; Switch to exception stack.
    LDR     SP, [R3]                                                                       
                        ;OS_CPU_ExceptStkBase 是一个128字节的数组  用作调用C语言函数堆栈使用?                                         ;这个SP堆栈应该是为了减少SVC模式堆栈的负荷量,单独是用高了一个堆栈区?
                                                                ; EXECUTE EXCEPTION HANDLER:
    LDR     R1, =OS_CPU_ExceptHndlr1                            ; OS_CPU_ExceptHndlr(except_type = R0)
    MOV     LR, PC
    BX      R1

                                                                ; Change to IRQ mode & disable interruptions.
    MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_IRQ)

                                                                ; Adjust exception stack pointer.  This is
    ADD     SP, SP, #(4 * 4)                                                               


                                                                ; Change to SVC mode & disable interruptions.
    MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)

                                                              
    LDR     R0, =OSIntExit                                                       
    MOV     LR, PC
    BX      R0

    LDR     R3, =OSTCBCur                                       ; SP = OSTCBCur->OSTCBStkPtr;
    LDR     R4,  [R3]
    LDR     SP,  [R4]
                                                                ; RESTORE NEW TASK'S CONTEXT:
    LDMFD   SP!, {R0}                                           ;    Pop new task's CPSR,
    MSR     SPSR_cxsf, R0

    LDMFD   SP!, {R0-R12, LR, PC}^                              ;    Pop new task's context.
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表