|
我按照网上的方法自己移植了个ucos2.92版本的
void Task1(void *ppdata)
{
ppdata = ppdata;
for(;;)
{
LED0 = ~LED0;
OSTimeDly(OS_TICKS_PER_SEC);
}
}
void Task2(void *ppdata)
{
ppdata = ppdata;
for(;;)
{
LED1=~LED1;
OSTimeDly(OS_TICKS_PER_SEC*2);
}
}
int main()
{
CKCON = 0x38;
Uart0_Init();
OSInit();
OSTaskCreate (Task1,(void *)0,&TaskStk[0][0],0);
OSTaskCreate (Task2,(void *)0,&TaskStk[1][0],1);
OSStart();
return 0;
}
我的问题是当task2运行到LED1=~LED1;
时发生了定时中断
执行
OSTickISR:
USING 0
CLR EA
PUSHALL
LCALL _?OSIntEnter
CLR TR0
MOV TH0,#0E0H
MOV TL0,#0C0H
SETB TR0
MOV WATCH,#0A1H
LCALL _?OSTimeTick
LCALL _?OSIntExit
POPALL
RETI
在定时中断里OSIntEnter ()--》OSTimeTick--》OSIntExit--》
void OSIntExit (void) reentrant
{
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
if (OSRunning == OS_TRUE) {
OS_ENTER_CRITICAL();
if (OSIntNesting > 0u) { /* Prevent OSIntNesting from wrapping */
OSIntNesting--;
}
if (OSIntNesting == 0u) { /* Reschedule only if all ISRs complete ... */
if (OSLockNesting == 0u) { /* ... and not locked. */
OS_SchedNew();
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
#if OS_TASK_PROFILE_EN > 0u
OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */
#endif
OSCtxSwCtr++; /* Keep track of the number of ctx switches */
OSIntCtxSw(); /* Perform interrupt level ctx switch */ }
}
}
OS_EXIT_CRITICAL();
}
}
OSIntCtxSw_in:
MOV A,SP
CLR C
SUBB A,#OSStkStart
MOV R5,A
MOV R0,#LOW (OSTCBCur)
INC R0
MOV DPH,@R0
INC R0
MOV DPL,@R0
INC DPTR
MOVX A,@DPTR
MOV R0,A
INC DPTR
MOVX A,@DPTR
MOV R1,A
MOV DPH,R0
MOV DPL,R1
MOV A,R5
MOVX @DPTR,A
MOV R0,#OSStkStart
save_stack:
INC DPTR
INC R0
MOV A,@R0
MOVX @DPTR,A
DJNZ R5,save_stack
INC DPTR
MOV A,?C_XBP
MOVX @DPTR,A
INC DPTR
MOV A,?C_XBP+1
MOVX @DPTR,A
LCALL _?OSTaskSwHook
MOV R0,#OSTCBCur
MOV R1,#OSTCBHighRdy
MOV A,@R1
MOV @R0,A
INC R0
INC R1
MOV A,@R1
MOV @R0,A
INC R0
INC R1
MOV A,@R1
MOV @R0,A
MOV R0,#OSPrioCur
MOV R1,#OSPrioHighRdy
MOV A,@R1
MOV @R0,A
LJMP OSCtxSw_in
;-------------------------------------------------------------------------
RSEG ?PR?OSIntCtxSw?OS_CPU_A
OSIntCtxSw:
MOV A,SP
CLR C
SUBB A,#4
MOV SP,A
LJMP OSIntCtxSw_in
在保存堆栈时怎么没有保存pc的值到仿真栈中呢?只保存了 栈长度 ACC B DPL DPH等
那么在下次轮到task2执行时RETI时怎么返回到LED1=~LED1;的下一行代码接着执行呢
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|