最近想重新看一下UCOSII,突发奇想,在中断退出的时候会发生任务的调度,假如连续得来中断,每次中断结束的时候都被调度到别的任务去执行,那样的话岂不是代码都在中断中运行,这样连续的占用堆栈,程序跑一会儿就会挂掉的,仔细思考一下,写ucosii的大神肯定考虑了各种情况的,不会出现这样的问题,何况现实中就没出现这样的问题,然后就分析ucosii的代码。
在退出中断的时候会调用OSIntExit,
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();
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
if (OSPrioHighRdy != OSPrioCur) {
#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();
}
}
}
OS_EXIT_CRITICAL();
}
}
在这段代码中有if (OSIntNesting == 0u) 这么一句,也就是说只有没有中断嵌套的时候才会发生实质性的调度,所以不会造成连续进中断的时候连续调度的问题。
然后又想到,如果在中断中post一个信号量,而走了那咋办,和上面说的情况不就是一样了吗,然后分析post信号量的函数,最后分析到任务调度的函数:
void OS_Sched (void)
{
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
OS_ENTER_CRITICAL();
if (OSIntNesting == 0u) { /* Schedule only if all ISRs done and ... */
if (OSLockNesting == 0u) { /* ... scheduler is 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++; / Increment context switch counter /
OS_TASK_SW(); / Perform a context switch */
}
}
}
OS_EXIT_CRITICAL();
}
其中也有一句if (OSIntNesting == 0u) ,也就是说只有在没有中断嵌套的时候才会发生任务的调度,所以以上担心仅仅是杞人忧天,不过这样也理解了一下,为什么写ucosii的大神写了判断OSIntNesting的那一句。不知道理解的是否正确,但是用这一句解释现在的问题是没有问题的。