#2
dadongwushen2016-05-13 21:30
|
近来想学习嵌入式系统,在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寄存器地址指向任务堆栈地址后程序运行起来也没发现什么不同。
目前程序运行后任务之间的切换正常,但是中断和任务之间切换多次之后会跑飞。
求大神解惑。