这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » ucosII,OSIntCtxSw ucosII 的函数OSIntCtxSw看不

共2条 1/1 1 跳转至

ucosII,OSIntCtxSw ucosII 的函数OSIntCtxSw看不懂的几个地方,请教周公

院士
2006-09-17 18:14:16     打赏
ucosII,OSIntCtxSw ucosII 的函数OSIntCtxSw看不懂的几个地方,请教周公



关键词: ucosII     OSIntCtxSw     函数     看不         

院士
2006-12-22 22:43:00     打赏
2楼
OSIntCtxSw
                                                   ;下面为保存任务环境
1       LDR     R2, [SP, #20]                       ;获取PC
2       LDR     R12, [SP, #16]                      ;获取R12
3       MRS     R0, CPSR
4       MSR     CPSR_c, #(NoInt | SYS32Mode)
5       MOV     R1, LR
6       STMFD   SP!, {R1-R2}                        ;保存LR,PC
7      STMFD   SP!, {R4-R12}                       ;保存R4-R12
8       MSR     CPSR_c, R0
9       LDMFD   SP!, {R4-R7}                        ;获取R0-R3
10       ADD     SP, SP, #8                          ;出栈R12,PC    
11       MSR     CPSR_c, #(NoInt | SYS32Mode)
  12      STMFD   SP!, {R4-R7}                        ;保存R0-R3      
13       LDR     R1, =OsEnterSum                     ;获取OsEnterSum
14       LDR     R2, [R1]
15       STMFD   SP!, {R2, R3}                   ;保存CPSR,OsEnterSum

                                 ;保存当前任务堆栈指针到当前任务的TCB
16      LDR     R1, =OSTCBCur
17      LDR     R1, [R1]
18      STR     SP, [R1]
19      BL      OSTaskSwHook                     ;调用钩子函数
                                        ;OSPrioCur <= OSPrioHighRdy
  20      LDR     R4, =OSPrioCur
  21      LDR     R5, =OSPrioHighRdy
  22      LDRB    R6, [R5]
  23      STRB    R6, [R4]
                                        ;OSTCBCur <= OSTCBHighRdy
  24      LDR     R6, =OSTCBHighRdy
  25      LDR     R6, [R6]
  26      LDR     R4, =OSTCBCur
  27      STR     R6, [R4]
OSIntCtxSw_1
                                                  ;获取新任务堆栈指针
  28      LDR     R4, [R6]
  29      ADD     SP, R4, #68                         ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
  30      LDR     LR, [SP, #-8]
  31     MSR     CPSR_c, #(NoInt | SVC32Mode)        ;进入管理模式
        MOV     SP, R4                              ;设置堆栈指针
  32     LDMFD   SP!, {R4, R5}                       ;CPSR,OsEnterSum
                                              ;恢复新任务的OsEnterSum
        LDR     R3, =OsEnterSum
        STR     R4, [R3]
    
        MSR     SPSR_cxsf, R5                       ;恢复CPSR
        LDMFD   SP!, {R0-R12, LR, PC }^             ;运行新任务

问1:前三行代码是不是运行在管理模式下,sp是不是管理模式下的堆栈指针?
  2:第31行为什么要进入管理模式,新任务的环境不是保存在用户模式下的任务堆栈吗?那接下来的MOV  SP, R4,R4的值为系统模式下的任务堆栈的指针,而sp为管理模式下的堆栈指针,那这两个堆栈不是重叠了?
  3:第28行,29行 ,30行作用是什么,好像没有什么目的,
  4:第32行,为什么r5为cpsr呢?狂看晕了.....
1: Re:xianfei5201:前三行代码是不是运行在管理模式下,sp是不是管理模式下的堆栈指针?
Ans: 周公的移植代码调用关系为:IRQ HANDLER(IRQ.inc文件中)->OSIntExit->OSIntCtxSw
我把IRQ.inc中的代码贴出来就清楚了:
        MSR     CPSR_c, #(NoInt | SYS32Mode)    ; 切换到系统模式
        LDR     R2, =OsEnterSum                 ; OsEnterSum,使OSIntExit退出时中断关闭
        MOV     R1, #1
        STR     R1, [R2]

        BL      OSIntExit

2: 4:第32行,为什么r5为cpsr呢?Ans:29      ADD     SP, R4, #68                         ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
29行的注释说该段代码的堆栈结构如:CPSR,OsEnterSum,R0-R12,LR,SP
经过LDMFD   SP!, {R4, R5}    ;CPSR,OsEnterSum
R4里面OsEnterSum
R5里面CPSR
3: 3:第28行,29行 ,30行作用是什么,好像没有什么目的,Ans:用作是访问堆栈成员,很多编译器生成的代码喜欢用SP+offset,即SP为基址外加偏移量的方式来访问堆栈里面的数据成员,这样有点类似于数组的下标索引,当访问第5个元素时,就不需要先把前四个元素Pop了。

偶觉得        ADD     SP, R4, #68                       
              LDR     LR, [SP, #-8]
看起来很混乱,若直接用LDR     LR, [SP, #-60],就可以了,真是很难理解为什么要先ADD 4: 2:第31行为什么要进入管理模式Ans:因为SWI会使ARM进入管理模式,这些操作可能跟SWI函数有关,楼主可以研究下zlg code的SWI部分 5: 非常感谢terrence的解答。还有些疑问,请教下;以下是在OS_CPU_s.s中的函数softwareinterrupt程序

;SoftwareInterrupt
      1)  LDR     SP, StackSvc            ;
     2)  STMFD   SP!, {R0-R3, R12, LR}
      3)  MOV     R1, SP                  ;

        MRS     R3, SPSR
        TST     R3, #T_bit              ;
        LDRNEH  R0, [LR,#-2]            ;
        BICNE   R0, R0, #0xff00
        LDREQ   R0, [LR,#-4]            ;
        BICEQ   R0, R0, #0xFF000000
                                        ;
        CMP     R0, #1
        LDRLO   PC, =OSIntCtxSw
        LDREQ   PC, =__OSStartHighRdy   ;

        BL      SWI_Exception
        
        LDMFD   SP!, {R0-R3, R12, PC}^
        
StackSvc           DCD     (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)
问题是:第一行中 LDR SP, StackSvc ,表示将StackSvc堆栈栈顶指针给三sp,这在什么模式下给的。。我估计是应该是在svc模式下,可是没有看到        MSR  CPSR_c, #(NoInt | SVC32Mode)的语句啊。。。
6: SWI使处理器进入SVC状态...正如IRQ使处理器进入IRQ状态一样 7: re 8: re:terrence:我今天调试了半天自己写的uc/os-ii的程序,
对于上面的知识有了直观的了解。。但是,对于uc/os-ii从main函数开始执行的顺序。今天郁闷惨了。。。。什么时候能求教一二不,,非常感谢老兄 9: 不错原来这里这么多ucOS高手!~ 10: re:terrence 兄。。 11: re:"3:第28行,29行 ,30行作用是什么,好像没有什么目的,

Ans:用作是访问堆栈成员,很多编译器生成的代码喜欢用SP+offset,即SP为基址外加偏移量的方式来访问堆栈里面的数据成员,这样有点类似于数组的下标索引,当访问第5个元素时,就不需要先把前四个元素Pop了。

偶觉得        ADD     SP, R4, #68                       
              LDR     LR, [SP, #-8]
看起来很混乱,若直接用LDR     LR, [SP, #-60],就可以了,真是很难理解为什么要先ADD"

  使用ADD     SP, R4, #68                       
      LDR     LR, [SP, #-8]
这两句是为了将sp指向pc+1之前的位置,这样的话,就不要会有资源浪费了。。
老兄可以把ostaskstkinit()确定的任务栈好好看看就知道了。。





共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]