📄 ——ucos51移植心得[社区].htm
字号:
<BR> MOV
R0,#OSStkStart ;获得堆栈起址<BR>save_stack:<BR>
<BR> INC
DPTR<BR> INC
R0<BR> MOV
A,@R0<BR> MOVX
@DPTR,A<BR> DJNZ
R5,save_stack<BR>
<BR>
;调用用户程序<BR> LCALL
_?OSTaskSwHook<BR>
<BR> ;OSTCBCur =
OSTCBHighRdy<BR> MOV
R0,#OSTCBCur<BR> MOV
R1,#OSTCBHighRdy<BR> MOV
A,@R1<BR> MOV
@R0,A<BR> INC
R0<BR> INC R1<BR>
MOV A,@R1<BR>
MOV @R0,A<BR>
INC R0<BR> INC
R1<BR> MOV
A,@R1<BR> MOV
@R0,A<BR>
<BR> ;OSPrioCur =
OSPrioHighRdy
使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。<BR>
MOV R0,#OSPrioCur<BR> MOV
R1,#OSPrioHighRdy<BR> MOV
A,@R1<BR> MOV
@R0,A<BR>
<BR> LJMP
OSCtxSw_in<BR>;-------------------------------------------------------------------------<BR>
RSEG
?PR?OSIntCtxSw?OS_CPU_A<BR>
<BR>OSIntCtxSw:</P>
<P>
;调整SP指针去掉在调用OSIntExit(),OSIntCtxSw()过程中压入堆栈的多余内容<BR>
;SP=SP-4</P>
<P> MOV
A,SP<BR> CLR
C<BR> SUBB
A,#4<BR> MOV
SP,A<BR>
<BR> LJMP
OSIntCtxSw_in<BR>;-------------------------------------------------------------------------<BR>
CSEG AT 000BH
;OSTickISR<BR> LJMP
OSTickISR
;使用定时器0<BR> RSEG
?PR?OSTickISR?OS_CPU_A</P>
<P>OSTickISR:
<BR>
<BR> USING
0
<BR>
PUSHALL<BR>
<BR> CLR
TR0<BR> MOV
TH0,#70H
;定义Tick=50次/秒(即0.02秒/次)<BR>
MOV TL0,#00H ;OS_CPU_C.C 和
OS_TICKS_PER_SEC<BR> SETB
TR0<BR>
<BR> LCALL
_?OSIntEnter<BR> LCALL
_?OSTimeTick<BR> LCALL
_?OSIntExit<BR>
POPALL
<BR>
RETI<BR>;-------------------------------------------------------------------------<BR>
CSEG AT 0023H
;串口中断<BR> LJMP
SerialISR
;工作于系统态,无任务切换。<BR> RSEG
?PR?_?serial?OS_CPU_A<BR>
<BR>SerialISR:<BR>
<BR> USING
0
<BR>
PUSHALL<BR> CLR
EA<BR> LCALL
_?serial
<BR> SETB
EA<BR>
POPALL
<BR>
RETI<BR>;-------------------------------------------------------------------------<BR>
END<BR>;-------------------------------------------------------------------------</P>
<P>文件名 : OS_CPU_C.C</P>
<P>void *OSTaskStkInit (void (*task)(void *pd), void *ppdata, void
*ptos, INT16U opt) reentrant<BR>{
<BR> OS_STK *stk;</P>
<P> ppdata = ppdata;<BR>
opt =
opt;
//opt没被用到,保留此语句防止告警产生 <BR>
stk = (OS_STK
*)ptos;
//用户堆栈最低有效地址<BR> *stk++ =
15;
//用户堆栈长度<BR> *stk++ = (INT16U)task &
0xFF;
//任务地址低8位<BR> *stk++ = (INT16U)task >>
8;
//任务地址高8位 <BR> *stk++ =
0x00;
//PSW<BR> *stk++ =
0x0A;
//ACC<BR> *stk++ =
0x0B;
//B<BR> *stk++ =
0x00;
//DPL<BR> *stk++ =
0x00;
//DPH<BR> *stk++ =
0x00;
//R0<BR> *stk++ =
0x01;
//R1<BR> *stk++ =
0x02;
//R2<BR> *stk++ =
0x03;
//R3<BR> *stk++ =
0x04;
//R4<BR> *stk++ =
0x05;
//R5<BR> *stk++ =
0x06;
//R6<BR> *stk++ =
0x07;
//R7<BR>
//不用保存SP,任务切换时根据用户堆栈长度计算得出。 <BR>
return ((void *)ptos);<BR>}</P>
<P>#if OS_CPU_HOOKS_EN<BR>void OSTaskCreateHook (OS_TCB *ptcb)
reentrant<BR>{<BR> ptcb =
ptcb;
/* Prevent compiler
warning
*/<BR>}</P>
<P>void OSTaskDelHook (OS_TCB *ptcb)
reentrant<BR>{<BR> ptcb =
ptcb;
/* Prevent compiler
warning
*/<BR>}</P>
<P>void OSTimeTickHook (void) reentrant<BR>{<BR>}<BR>#endif</P>
<P>//初始化定时器0<BR>void InitTimer0(void)
reentrant<BR>{<BR>
TMOD=TMOD&0xF0;<BR>
TMOD=TMOD|0x01;
//模式1(16位定时器),仅受TR0控制<BR>
TH0=0x70;
//定义Tick=50次/秒(即0.02秒/次)<BR>
TL0=0x00; //OS_CPU_A.ASM 和
OS_TICKS_PER_SEC<BR>
ET0=1;
//允许T0中断<BR> TR0=1; <BR>}</P>
<P>文件名 : YY.C</P>
<P>#include <includes.h></P>
<P>#define MAX_STK_SIZE 64</P>
<P>void TaskStartyya(void *yydata) reentrant;<BR>void
TaskStartyyb(void *yydata) reentrant;<BR>void TaskStartyyc(void
*yydata) reentrant;</P>
<P>OS_STK
TaskStartStkyya[MAX_STK_SIZE+1];//注意:我在ASM文件中设置?STACK空间为40H即64,不要超出范围。<BR>OS_STK
TaskStartStkyyb[MAX_STK_SIZE+1];//用户栈多一个字节存长度<BR>OS_STK
TaskStartStkyyc[MAX_STK_SIZE+1];</P>
<P>void main(void)<BR>{<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -