530991163 发表于 2011-11-26 07:44

关于uc/os-II的任务切换时压栈的问题

大家好:
         我最近在学习UCOS,我用的freescale的16位单片机,想请教一下当任务切换时,被剥夺CPU使用权的任务的状态(即任务CPU状态和寄存器值)是怎么压入该任务的任务堆栈中的,我看代码中只是将堆栈指针保存了一下,因为uc/os实际上是通过软中断指令来进行任务的切换,当CPU执行软中断指令时,当前任务状态被压入默认的一个堆栈中去了,怎么才能将这个堆栈设为任务堆栈呢?这块我还不是太明白,理解可能不正确,请大家指教~~谢谢了~~

wjvictor 发表于 2012-2-27 17:35

期待中?

delin17 发表于 2012-2-28 12:41

我印象中是压入当前任务堆载,然后再切到要最高优先任务中堆栈,弹出该任务上次保存的状态。

delin17 发表于 2012-2-28 12:43

具体细节看那个切换函数。OSPendSV
      IF OS_CRITICAL_INT_PRIO > 0                                            ;disable interupt 禁能中断
                  MRS R3, BASEPRI
            LDR R1, =OS_CRITICAL_INT_PRIO
                        MSR BASEPRI, R1
                ELSE
              MRS   R3, PRIMASK
              CPSID   I
                ENDIF


                MRS   R0, PSP                                                 ;PSP is process stack pointer
                                                                        ;PSP是任务的堆栈指针
      CBZ   R0, OSPendSV_nosave                                     ;skip register save the first
                                                                        ;time第一次跳过保存

      SUB   R0, R0, #0x20                                           ;save remaining regs r4-11 on
                                                                        ;process stack 保存r4-r11
      STM   R0, {R4-R11}

      LDR   R4, =OSTCBCur                                           ;OSTCBCur->OSTCBStkPtr = SP;
      LDR   R4,
      STR   R0,                                                 ;R0 is SP of process being
                                                                        ;switched outR0是被切换开的任务
                                                                        ;的堆栈指针
OSPendSV_nosave
      PUSH    {R14}                                                   ;need to save LR exc_return
                                                                        ;value保存LR返回值

      LDR   R0, =OSTaskSwHook                                       ;OSTaskSwHook();
      BLX   R0
      POP   {R14}

      LDR   R4, =OSPrioCur                                          ;OSPrioCur = OSPrioHighRdy
      LDR   R5, =OSPrioHighRdy
      LDRB    R6,
      STRB    R6,

      LDR   R4, =OSTCBCur                                           ;OSTCBCur= OSTCBHighRdy;
      LDR   R6, =OSTCBHighRdy
      LDR   R6,
      STR   R6,

      LDR   R0,                                                 ;SP = OSTCBHighRdy->OSTCBStkPtr;
      LDM   R0, {R4-R11}                                          ;restore r4-11 from new process
                                                                        ;stack 从新任务的堆栈恢复r4-r11
      ADD   R0, R0, #0x20
      MSR   PSP, R0                                                 ;load PSP with new process SP
                                                                        ;从新任务的堆栈恢复PSP

      ORR   LR, LR, #0x04                                           ;ensure exception return uses
                                                                        ;PSP确保返回后使用PSP

                IF OS_CRITICAL_INT_PRIO > 0                                     ;restore interrupts 恢复中断
                  MSR         BASEPRI,R3
                ELSE
                        MSR   PRIMASK, R3
                ENDIF

          BX      LR                                                      ; exception return will restore
                                                                        ;remaining context
                                                                        ;返回时会恢复剩下的上下文
      NOP

mdcy278 发表于 2012-2-28 13:07

在压栈以前已经把任务堆栈的指针赋给了SP寄存器吧。看贝贝的书上是这么说的。

zhaigch 发表于 2012-3-2 21:47

具体的压栈过程是要自己写汇编代码来实现的!UCOS里只是调用调度函数!如LS所说,被切换的任务,把自己的数据存储下来,然后把新任务的堆栈块指针给SP。。。从而来实现任务的切换!好像是这样的,好久不看那个了!LZ自己再看看书上的源代码!

denghaibo 发表于 2012-3-7 19:22

是压入当前任务栈,再切换的
页: [1]
查看完整版本: 关于uc/os-II的任务切换时压栈的问题