?? ——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 + -