打印

ucos移植osintctxsw的困惑!

[复制链接]
3867|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
areshan|  楼主 | 2010-12-6 11:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
OSIntCtxSw
                                                    ;下面为保存任务环境
        LDR     R2, [SP, #20]                       ;获取PC
        LDR     R12, [SP, #16]                      ;获取R12
        MRS     R0, CPSR

        MSR     CPSR_c, #(NoInt | SYS32Mode)
        MOV     R1, LR
        STMFD   SP!, {R1-R2}                        ;保存LR,PC
        STMFD   SP!, {R4-R12}                       ;保存R4-R12

        MSR     CPSR_c, R0
        LDMFD   SP!, {R4-R7}                        ;获取R0-R3
        ADD     SP, SP, #8                          ;出栈R12,PC
        
        MSR     CPSR_c, #(NoInt | SYS32Mode)
        STMFD   SP!, {R4-R7}                        ;保存R0-R3
        
        LDR     R1, =OsEnterSum                     ;获取OsEnterSum
        LDR     R2, [R1]
        STMFD   SP!, {R2, R3}                       ;保存CPSR,OsEnterSum
                                                    ;保存当前任务堆栈指针到当前任务的TCB
        LDR     R1, =OSTCBCur
        LDR     R1, [R1]
        STR     SP, [R1]
        BL      OSTaskSwHook                        ;调用钩子函数
                                                    ;OSPrioCur <= OSPrioHighRdy
        LDR     R4, =OSPrioCur
        LDR     R5, =OSPrioHighRdy
        LDRB    R6, [R5]
        STRB    R6, [R4]
                                                    ;OSTCBCur <= OSTCBHighRdy
        LDR     R6, =OSTCBHighRdy
        LDR     R6, [R6]
        LDR     R4, =OSTCBCur
        STR     R6, [R4]
OSIntCtxSw_1
                                                    ;获取新任务堆栈指针
        LDR     R4, [R6]
        ADD     SP, R4, #68                         ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
        LDR     LR, [SP, #-8]
        MSR     CPSR_c, #(NoInt | SVC32Mode)        ;进入管理模式
        MOV     SP, R4                              ;设置堆栈指针
        LDMFD   SP!, {R4, R5}                       ;CPSR,OsEnterSum
                                                    ;恢复新任务的OsEnterSum
        LDR     R3, =OsEnterSum
        STR     R4, [R3]
   
        MSR     SPSR_cxsf, R5                       ;恢复CPSR
        LDMFD   SP!, {R0-R12, LR, PC }^             ;运行新任务
上面红色的部分看不懂,这段函数是任务切换函数,和中断任务切换。中断任务切换和任务切换的有一部分一样,所以共用。任务切换就是把低优先级的任务入栈,高优先级的任务出栈。
ARM7的特殊性,有7中工作模式。任务工作在系统模式或用户模式。其他的模式都是用异常进入的。
上面的代码让我和困惑,LDR R2,[SP,#20];怎么是获取PC值呢,这个PC应该是该函数上次保存的吧,这次的任务切换应该给它覆盖掉,因为要保持PC也是要从当前的工作寄存器中读取呀。还有就是R12有什么特殊的意义没有,问什么要单独保存。R0-R3,和R4-R11也不同,是什么规则???ATPCS只是ARM,THUMB程序调用规则,和你要保存的寄存器也没有什么关系呀!!!!!!!十分不理解上面的代码到底是怎么来的,有什么规则吗?还请各位高手给点指点,谢谢大家了!!!!!!

相关帖子

沙发
areshan|  楼主 | 2010-12-6 17:38 | 只看该作者
OSCtxSw       
STMFD        SP!, {LR}           ;保存返回的PC值 因为是从OS_Sched()跳转这里的
        STMFD        SP!, {R0-R12,LR}   ;R0-R12 LR
        MRS                R0,  CPSR               ;保存CPSR
        STMFD        SP!, {R0}                       
        LDR                R0, =OSTCBCur                ;把当前任务的栈顶指针保存到当前任务TCB控制块的堆栈指针变量中
        LDR                R0, [R0]
        STR                SP, [R0]
        BL                 OSTaskSwHook
        LDR                R0, =OSTCBHighRdy   ;设置最高优先级控制块堆栈指针到当前优先级任务控制块堆栈指针变量中
        LDR                R1, =OSTCBCur
        LDR                R0, [R0]                       
        STR                R0, [R1]                               
        LDR                R0, =OSPrioHighRdy        ;设置最高优先级到当前优先级变量中
        LDR                R1, =OSPrioCur
        LDRB        R0, [R0]
        STRB        R0, [R1]
        LDR                R0, =OSTCBHighRdy        ;获取最高优先级控制块堆栈指针 此时 堆栈已经切换了
        LDR                R0, [R0]
        LDR                SP, [R0]
        LDMFD         SP!, {R0}                                ;从栈顶取得CPSR  (从前备份的当前状态 相当于SPSR的备份)
        MSR         SPSR_cxsf, R0                        ;恢复SPSR
        LDMFD         SP!, {R0-R12, LR, PC}^        ;任务切换 (同时 把SPSR复制到当前CPSR)

个人觉得这个要好理解的多!!!!!!晚上回来再好好看看!!!!!!

使用特权

评论回复
板凳
tigerchen| | 2010-12-6 22:36 | 只看该作者
很好啊

使用特权

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

本版积分规则

127

主题

728

帖子

0

粉丝