uCOS51移植心得[社区]
MOV @R0,A
;OSPrioCur = OSPrioHighRdy 使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。
MOV R0,#OSPrioCur
MOV R1,#OSPrioHighRdy
MOV A,@R1
MOV @R0,A
LJMP OSCtxSw_in
;-------------------------------------------------------------------------
RSEG ?PR?OSIntCtxSw?OS_CPU_A
OSIntCtxSw:
;调整SP指针去掉在调用OSIntExit(),OSIntCtxSw()过程中压入堆栈的多余内容
;SP=SP-4
MOV A,SP
CLR C
SUBB A,#4
MOV SP,A
LJMP OSIntCtxSw_in
;-------------------------------------------------------------------------
CSEG AT 000BH ;OSTickISR
LJMP OSTickISR ;使用定时器0
RSEG ?PR?OSTickISR?OS_CPU_A
OSTickISR:
USING 0
PUSHALL
CLR TR0
MOV TH0,#70H ;定义Tick=50次/秒(即0.02秒/次)
MOV TL0,#00H ;OS_CPU_C.C 和 OS_TICKS_PER_SEC
SETB TR0
LCALL _?OSIntEnter
LCALL _?OSTimeTick
LCALL _?OSIntExit
POPALL
RETI
;-------------------------------------------------------------------------
CSEG AT 0023H ;串口中断
LJMP SerialISR ;工作于系统态,无任务切换。
RSEG ?PR?_?serial?OS_CPU_A
SerialISR:
USING 0
PUSHALL
CLR EA
LCALL _?serial
SETB EA
POPALL
RETI
;-------------------------------------------------------------------------
END
;-------------------------------------------------------------------------
文件名 : OS_CPU_C.C
void *OSTaskStkInit (void (*task)(void *pd), void *ppdata, void *ptos, INT16U opt) reentrant
{
OS_STK *stk;
ppdata = ppdata;
opt = opt; //opt没被用到,保留此语句防止告警产生
stk = (OS_STK *)ptos; //用户堆栈最低有效地址
*stk++ = 15; //用户堆栈长度
*stk++ = (INT16U)task & 0xFF; //任务地址低8位
*stk++ = (INT16U)task >> 8; //任务地址高8位
*stk++ = 0x00; //PSW
*stk++ = 0x0A; //ACC
*stk++ = 0x0B; //B
*stk++ = 0x00; //DPL
*stk++ = 0x00; //DPH
*stk++ = 0x00; //R0
*stk++ = 0x01; //R1
*stk++ = 0x02; //R2
*stk++ = 0x03; //R3
*stk++ = 0x04; //R4
*stk++ = 0x05; //R5
*stk++ = 0x06; //R6
*stk++ = 0x07; //R7
//不用保存SP,任务切换时根据用户堆栈长度计算得出。
return ((void *)ptos);
}
#if OS_CPU_HOOKS_EN
void OSTaskCreateHook (OS_TCB *ptcb) reentrant
{
ptcb = ptcb; /* Prevent compiler warning */
}
void OSTaskDelHook (OS_TCB *ptcb) reentrant
{
ptcb = ptcb; /* Prevent compiler warning */
}
void OSTimeTickHook (void) reentrant
{
}
#endif
//初始化定时器0
void InitTimer0(void) reentrant
{
TMOD=TMOD&0xF0;
TMOD=TMOD0x01; //模式1(16位定时器),仅受TR0控制
TH0=0x70; //定义Tick=50次/秒(即0.02秒/次)
TL0=0x00; //OS_CPU_A.ASM 和 OS_TICKS_PER_SEC
ET0=1; //允许T0中断
TR0=1;
}
文件名 : YY.C
#include
#define MAX_STK_SIZE 64
void TaskStartyya(void *yydata) reentrant;
void TaskStartyyb(void *yydata) reentrant;
void TaskStartyyc(void *yydata) reentrant;
OS_STK TaskStartStkyya[MAX_STK_SIZE+1];//注意:我在ASM文件中设置?STACK空间为40H即64,不要超出范围。
OS_STK TaskStartStkyyb[MAX_STK_SIZE+1];//用户栈多一个字节存长度
OS_STK TaskStartStkyyc[MAX_STK_SIZE+1];
void main(void)
{
OSInit();
InitTimer0();
InitSerial();
InitSerialBuffer();
OSTaskCreate(TaskStartyya, (void *)0, &TaskStartStkyya[0],2);
OSTaskCreate(TaskStartyyb, (void *)0, &TaskStartStkyyb[0],3);
OSTaskCreate(TaskStartyyc, (void *)0, &TaskStartStkyyc[0],4);
OSStart();
}
void TaskStartyya(void *yydata) reentrant
{
yydata=yydata;
clrscr();
PrintStr("\n\t\t*******************************\n");
PrintStr("\t\t* Hello! The world. *\n");
PrintStr("\t\t*******************************\n\n\n");
for(;;){
PrintStr("\tAAAAAA111111 is active.\n");
OSTimeDly(OS_TICKS_PER_SEC);
}
}
void TaskStartyyb(void *yydata) reentrant
{
yydata=yydata;
for(;;){
PrintStr("\tBBBBBB333333 is active.\n");
OSTimeDly(3*OS_TICKS_PER_SEC);
}
}
void TaskStartyyc(void *yydata) reentrant
{
yydata=yydata;
for(;;){
PrintStr("\tCCCCCC666666 is active.\n");
OSTimeDly(6*OS_TICKS_PER_SEC);
}
}
* - 本贴最后修改时间:2003-5-29 11:25:08 修改者:gdtyy
* - 修改原因:+
作者信箱 asdjf@163.com
社区原文 asp?boardid=8&page=1&t=338692&tp=uCOS51%u79FB%u690D%u5FC3%u5F97">http://www.21icbbs.com/club/bbs/list.asp?boardid=8&page=1&t=338692&tp=uCOS51%u79FB%u690D%u5FC3%u5F97