51操作系统 2009-04-17 14:45:23 阅读131 评论1 字号:大中小
OSCtxSw():
如果当前任务调用Small RTOS 51提供的系统服务,并使得更高优先级任务处于就绪状态,Small RTOS 51就会借助上面提到的向量地址找到OSCtxSw()。在系统服务调用的最后,Small RTOS 51会调用OSSched(),并由此来推断当前任务不再是要运行的最重要的任务了。OSSched()先将最高优先级任务的ID放到变量OSNEXTASKID中,并使处理器执行OSCtxSw()。这些代码必须写在汇编语言中,因为用户不能直接从C中访问CPU寄存器。注意在OSCtxSw()中中断是禁止的。
OSCtxSw()的程序结构 |
void OSCtxSw(void) |
{ |
保存处理器寄存器; |
将当前任务的指针保存到堆栈中: |
查到下一个就绪的优先级最高的任务的ID |
得到需要恢复的任务的堆栈指针: |
调用C_OSCtxSw堆栈处理函数进行任务堆栈的搬移 |
将所有处理器寄存器从新任务的堆栈中恢复出来; |
执行中断返回指令; |
} |
程序源代码如下:
/*******************************
** 函数名称: C_OSCtxSw
** 功能描述: 堆栈处理函数
** 输 入: 无
** 输 出: 无
全局变量: OSTaskID,OSTsakStackBotton,SP
**调用模块: LoadCtx
*********************************
RSEG ?PR?C_OSCtxSw?OS_CPU_C
PUSH Os_Enter_Sum ;保存关中断计数器
mov r2,sp
MOV R0,SP
IF EN_SP2 <> 0
mov sp,#(Sp2-1) ;堆栈指向临时空间,允许“软非屏蔽中断”
ENDIF
INC R0
MOV A,#LOW (OSTsakStackBotton+01H)
ADD A,OSNextTaskID
MOV R1,A
MOV A,@R1
MOV R7,A
MOV A,#LOW (OSTsakStackBotton+01H)
ADD A,OSTaskID
MOV R1,A
MOV A,@R1
MOV R1,A
MOV A,OSNextTaskID
SETB C
SUBB A,OSTaskID
JC ?C0001
MOV A,R7
CLR C
SUBB A,R1
MOV R6,A
?C0002:
MOV A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R6,?C0002
?C0003:
MOV A,#LOW (OSTsakStackBotton+1)
ADD A,OSTaskID
MOV R1,A
MOV A,@R1
SETB C
;SUBB A,sp
SUBB A,r2
MOV R7,A
DEC R0;
MOV SP,R0
MOV A,OSNextTaskID
CLR C
SUBB A,OSTaskID
MOV R6,A
JZ ?C0005
MOV A,#LOW (OSTsakStackBotton)
ADD A,OSTaskID
MOV R1,A
MOV A,R7
CPL A
INC A
MOV R7,A
?C0004:
INC R1
MOV A,R7
ADD A,@R1
MOV @R1,A
DJNZ R6,?C0004
?C0005:
MOV OSTaskID,OSNextTaskID
LJMP LoadCtx
?C0001:
MOV A,OSNextTaskID
XRL A,OSTaskID
JZ ?C000r
;MOV A,R7
;CLR C
;SUBB A,R1
;MOV R6,A
mov a,r0
clr c
subb a,r7
mov r6,a
?C0008:
DEC R0
DEC R1
MOV A,@R0
MOV @R1,A
DJNZ R6,?C0008
?C0009:
MOV A,#LOW (OSTsakStackBotton+01H)
ADD A,OSTaskID
MOV R1,A
MOV A,@R1
SETB C
;SUBB A,SP
SUBB A,r2
MOV R7,A
MOV A,#LOW (OSTsakStackBotton+01H)
ADD A,OSNextTaskID
MOV R1,A
MOV A,@R1
MOV SP,A
MOV A,OSTaskID
http://xky19870905.blog.163.com/blog/static/51855417200931724523879/
文章评论(0条评论)
登录后参与讨论