V A,@R1 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 社区原文 http://www.21icbbs.com/club/bbs/list.asp?boardid=8&page=1&t=338692&tp=uCOS51%u79FB%u690D%u5FC3%u5F97 |