注册 登录
编程论坛 操作系统内核开发

uCOS-II移植中任务切换的问题

zcswinner 发布于 2014-12-20 18:13, 5250 次点击
近来想学习嵌入式系统,在ATmega8单片机下跑了个UCOS系统。虽然完成了任务切换,但是对于涉及到的几个内核函数任由疑问:
OSCtxSw()代码如下:
OSCtxSw:
                PUSH_ALL                            ; Save current task's context
                PUSH_SREG
                PUSH_SP

                LDS     R30,OSTCBCur               ; Z = OSTCBCur->OSTCBStkPtr
                LDS     R31,OSTCBCur+1             ;
                ST      Z+,R28                      ; Save Y (R29:R28) pointer
                ST      Z+,R29                      ;

                RCALL    OSTaskSwHook               ; Call user defined task switch hook

                LDS     R16,OSPrioHighRdy          ; OSPrioCur = OSPrioHighRdy
                STS     OSPrioCur,R16

                LDS     R30,OSTCBHighRdy           ; Let Z point to TCB of highest priority task
                LDS     R31,OSTCBHighRdy+1         ; ready to run
                STS     OSTCBCur,R30               ; OSTCBCur = OSTCBHighRdy
                STS     OSTCBCur+1,R31             ;

                LD      R28,Z+                      ; Restore Y pointer
                LD      R29,Z+                      ;

                POP_SP                              ; Restore stack pointer
                LD      R16,Y+
                SBRC    R16,7
                RJMP    OSCtxSw_1
               
                OUT     SREG,R16                    ; Restore status register
                POP_ALL                             ; Restore all registers
                RET
OSCtxSw_1:
                CBR     R16,BIT07
                OUT     SREG,R16
                POP_ALL
                RETI
其中PUSH_ALL用来保存CPU寄存器,其代码如下:
.macro  PUSH_ALL                            ; Save all registers
                ST      -Y,R0
                ST      -Y,R1
                ST      -Y,R2
                ST      -Y,R3
                ST      -Y,R4
                ST      -Y,R5
                ST      -Y,R6
                ST      -Y,R7
                ST      -Y,R8
                ST      -Y,R9
                ST      -Y,R10
                ST      -Y,R11
                ST      -Y,R12
                ST      -Y,R13
                ST      -Y,R14
                ST      -Y,R15
                ST      -Y,R16
                ST      -Y,R17
                ST      -Y,R18
                ST      -Y,R19
                ST      -Y,R20
                ST      -Y,R21
                ST      -Y,R22
                ST      -Y,R23
                ST      -Y,R24
                ST      -Y,R25
                ST      -Y,R26
                ST      -Y,R27
                ST      -Y,R30
                ST      -Y,R31
                IN      R16,RAMPZ
                ST      -Y,R16
                .endm
该函数实在任务调度函数OS_Sched()里调用的,但是OS_Sched()调用它之前也并没有把Y寄存器指向该任务堆栈栈顶地址,有大神知道这是怎么回事吗?中断任务切换函OSIntCtxSw()也是如此,直接PUSH_ALL、PUSH_SREG、PUSH_SP,并未指定被中断的任务的堆栈栈顶地址。我自己手动在保存CPU状态之前把Y寄存器地址指向任务堆栈地址后程序运行起来也没发现什么不同。
目前程序运行后任务之间的切换正常,但是中断和任务之间切换多次之后会跑飞。
求大神解惑。
1 回复
#2
dadongwushen2016-05-13 21:30
我用的是,51里面的ucos,根据51,栈底位置在在系统初始化的时候就已经设定了,在程序运行过程中,栈的大小是sp的位置减去栈底位置,我们的任务堆栈里保存的硬件栈信息包括任务切换前的地址值,以及所有寄存器的值。
1