小弟这几天移植uCOS系统的时候,
发现了一个问题,
就是系统时钟我用TIM模块记时的时候程序能正常运行,
但是我把记时的方式改成了PIT中断记时,程序就开始跑飞了。
整个人都是懵逼的,ILLEGAL_BP是什么鬼。
尼玛这不科学啊,虽然TIM模块能跑,但是我就是喜欢用PIT,问我为啥?我喜欢,任性!
于是我就走上了debug的不归路,xs128的datasheet被我看了一次又一次,
然并卵,我发现我的中断没问题啊。
终于在今天,我开始了一遍有一遍的单步调试
终于 在程序跑到了嘀嗒时钟的OSIntExit()时,问题出现了
在执行了OSIntCtxSw()的最后一句时,编译器提示我单片机自动复位了!
问题就是这个!
我赵日天第一个表示不服,为啥我在网上下载的uCOS移植好了的程序用PIT定时就可以跑!
默默的点开了网上大神写的程序,开始默默比对 终于发现了不一样的地方
我的程序长这样
void OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
OSIntNesting--;
}
if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ... */
OSIntExitY = OSUnMapTbl[OSRdyGrp]; /* ... and not locked. */
OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++; /* Keep track of the number of context switches */
OSIntCtxSw(); /* Perform interrupt level context switch */
}
}
OS_EXIT_CRITICAL();
}
大神的程序长这样void OSIntExit (void)
{
#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();
OS_Sched();
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()!!!!!
然后我的程序改成了这样 他就能正常巡行了void OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_ENTER_CRITICAL();
// if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
// OSIntNesting--;
// }
// if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ... */
// OSIntExitY = OSUnMapTbl[OSRdyGrp]; /* ... and not locked. */
// OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
// if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
// OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
// OSCtxSwCtr++; /* Keep track of the number of context switches */
// OSIntCtxSw(); /* Perform interrupt level context switch */
// }
// }
if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
OSIntNesting--;
}
if ((OSIntNesting == 0) && (OSLockNesting == 0)) {
OS_Sched();
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
if (OSPrioHighRdy != OSPrioCur) {
OSCtxSwCtr++;
OSIntCtxSw();
}
}
OS_EXIT_CRITICAL();
}
所以 今天的问题是
OSCtxSw()和OSIntCtxSw()有啥区别 到底啥时候用啥 |