当前位置: 技术问答>linux和unix
关于ucosII中调度算法
来源: 互联网 发布时间:2016-06-27
本文导语: OSTimeTick OS_Sched OS_TASK_SW OSCtxSw OSIntCtxSw 我想知道它究竟是这么切换的任务。 具体说来就是什么时候调用什么函数,并在这个函数中做了什么来完成任务切换的? 这个问题,貌似得对ucos稍微有点研究,如果需要可以加...
OSTimeTick
OS_Sched
OS_TASK_SW OSCtxSw
OSIntCtxSw
我想知道它究竟是这么切换的任务。
具体说来就是什么时候调用什么函数,并在这个函数中做了什么来完成任务切换的?
这个问题,貌似得对ucos稍微有点研究,如果需要可以加分,谢谢了!
OS_Sched
OS_TASK_SW OSCtxSw
OSIntCtxSw
我想知道它究竟是这么切换的任务。
具体说来就是什么时候调用什么函数,并在这个函数中做了什么来完成任务切换的?
这个问题,貌似得对ucos稍微有点研究,如果需要可以加分,谢谢了!
|
uC/OS-II源码分析
在Task中,一般执行一段时间之后调用OSTimeDly推迟一段时间再继续运行,OSTimeDly将本进程从Ready TCBList中删除,然后将Delay的时间设置给OSTCBDly,最后调用OS_Sched进行进程调度。
void OSTimeDly (INT16U ticks)
{
INT8U y;
if (ticks > 0) {
OS_ENTER_CRITICAL();
y = OSTCBCur->OSTCBY;
OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
if (OSRdyTbl[y] == 0) {
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
OSTCBCur->OSTCBDly = ticks;
OS_EXIT_CRITICAL();
OS_Sched();
}
}
如果ticks为零,说明不需延迟,则什么事情都不做。否则,调用OS_ENTER_CRITICAL进入临界段,将本进程从Ready TCBList中删除的代码如下:
y = OSTCBCur->OSTCBY;
OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
if (OSRdyTbl[y] == 0) {
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
y为当前进程所在Group,OSRdyTbl[y]为该Group所在字节,&=~则将该字节中本进程所占用的Bit清零。如果OSRdyTbl[y]为0,则说明这个Group中没有进程处于Ready状态,则将OSRdyGrp中该Group所占用的Bit清零。
然后将ticks保存在OSTCBDly中,每次OSTimeTick运行时会将这个值减一直至为零。
调用OS_EXIT_CRITICAL离开临界段,紧接着调用OS_Sched进入调度例程。
OS_Sched
OS_Sched是进程调度所使用的函数,在这里面找到最高优先级的进程,然后切换到该进程运行。
void OS_Sched (void)
{
INT8U y;
OS_ENTER_CRITICAL();
if (OSIntNesting == 0) {
if (OSLockNesting == 0) {
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y OSTCBDly != 0) {
if (--ptcb->OSTCBDly == 0) {
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY;
ptcb->OSTCBPendTO = TRUE;
} else {
ptcb->OSTCBPendTO = FALSE;
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
}
}
}
ptcb = ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
}
首先在临界段将OSTime加一,然后遍历整个非Free的TCBList,如果OSTCBDly不为0,则,将OSTCBDly减一,如果这时OSTCBDly为0,而且TCB对应的进程需要等待任何信号量或Event等,则说明超时时间到了,将当前TCB的State中OS_STAT_PEND_ANY位去掉,然后将OSTCBPendTo设置为TRUE,表示这是PEND的超时,否则设置OSTCBPendTO为FALSE。
如果OSTCBDly减为零,且该进程没有Suspend,则将该进程放入Ready TCBList中,使用方法同TaskCreate中的方法。
然后我们来说说OSIntExit这个函数。该函数代码如下:
void OSIntExit (void)
{
INT8U y;
if (OSRunning == TRUE) {
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) {
OSIntNesting--;
}
if (OSIntNesting == 0) {
if (OSLockNesting == 0) {
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y
在Task中,一般执行一段时间之后调用OSTimeDly推迟一段时间再继续运行,OSTimeDly将本进程从Ready TCBList中删除,然后将Delay的时间设置给OSTCBDly,最后调用OS_Sched进行进程调度。
void OSTimeDly (INT16U ticks)
{
INT8U y;
if (ticks > 0) {
OS_ENTER_CRITICAL();
y = OSTCBCur->OSTCBY;
OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
if (OSRdyTbl[y] == 0) {
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
OSTCBCur->OSTCBDly = ticks;
OS_EXIT_CRITICAL();
OS_Sched();
}
}
如果ticks为零,说明不需延迟,则什么事情都不做。否则,调用OS_ENTER_CRITICAL进入临界段,将本进程从Ready TCBList中删除的代码如下:
y = OSTCBCur->OSTCBY;
OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
if (OSRdyTbl[y] == 0) {
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
y为当前进程所在Group,OSRdyTbl[y]为该Group所在字节,&=~则将该字节中本进程所占用的Bit清零。如果OSRdyTbl[y]为0,则说明这个Group中没有进程处于Ready状态,则将OSRdyGrp中该Group所占用的Bit清零。
然后将ticks保存在OSTCBDly中,每次OSTimeTick运行时会将这个值减一直至为零。
调用OS_EXIT_CRITICAL离开临界段,紧接着调用OS_Sched进入调度例程。
OS_Sched
OS_Sched是进程调度所使用的函数,在这里面找到最高优先级的进程,然后切换到该进程运行。
void OS_Sched (void)
{
INT8U y;
OS_ENTER_CRITICAL();
if (OSIntNesting == 0) {
if (OSLockNesting == 0) {
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y OSTCBDly != 0) {
if (--ptcb->OSTCBDly == 0) {
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY;
ptcb->OSTCBPendTO = TRUE;
} else {
ptcb->OSTCBPendTO = FALSE;
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
}
}
}
ptcb = ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
}
首先在临界段将OSTime加一,然后遍历整个非Free的TCBList,如果OSTCBDly不为0,则,将OSTCBDly减一,如果这时OSTCBDly为0,而且TCB对应的进程需要等待任何信号量或Event等,则说明超时时间到了,将当前TCB的State中OS_STAT_PEND_ANY位去掉,然后将OSTCBPendTo设置为TRUE,表示这是PEND的超时,否则设置OSTCBPendTO为FALSE。
如果OSTCBDly减为零,且该进程没有Suspend,则将该进程放入Ready TCBList中,使用方法同TaskCreate中的方法。
然后我们来说说OSIntExit这个函数。该函数代码如下:
void OSIntExit (void)
{
INT8U y;
if (OSRunning == TRUE) {
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) {
OSIntNesting--;
}
if (OSIntNesting == 0) {
if (OSLockNesting == 0) {
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
站内导航:
特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!