微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > μC/OS-II的任务管理

μC/OS-II的任务管理

时间:10-08 来源:互联网 点击:

μC/OS-Ⅱ支持的处理器的堆栈既可以从上(高地址)往下(低地址)递减也可以从下往上递增。用户在调用OSTaskCreate()的时候必须知道堆栈是递增的还是递减的(参看所用处理器的OS_CPU.H中的OS_STACK_GROWTH),因为用户必须得把堆栈的栈顶传递给OSTaskCreate(), 而栈顶可能是堆栈的最高地址(堆栈从上往下递减), 也可能是最低地址(堆栈从下往上长)。

一旦OSTaskStkInit()函数完成了建立堆栈的任务,OSTaskCreate()就调用OSTCBInit()[L4.1(6)],从空闲的OS_TCB池中获得并初始化一个OS_TCB。OSTCBInit()的代码如程序清单L4.2所示,它存在于0S_CORE.C文件中而不是OS_TASK.C文件中。

OSTCBInit()函数首先从OS_TCB缓冲池中获得一个OS_TCB[L4.2(1)],如果OS_TCB池中有空闲的OS_TCB[L4.2(2)],它就被初始化[L4.2(3)]。注意一旦OS_TCB被分配,该任务的创建者就已经完全拥有它了,即使这时内核又创建了其它的任务,这些新任务也不可能对已分配的OS_TCB作任何操作,所以OSTCBInit()在这时就可以允许中断,并继续初始化OS_TCB的数据单元。

程序清单 L4.2 OSTCBInit()

INT8UOSTCBInit(INT8Uprio,OS_STK*ptos,OS_STK*pbos,INT16Uid,

INT16Ustk_size,void*pext,INT16Uopt)

{

OS_TCB*ptcb;

OS_ENTER_CRITICAL();

ptcb=OSTCBFreeList;(1)

if(ptcb!=(OS_TCB*)0){(2)

OSTCBFreeList=ptcb->OSTCBNext;

OS_EXIT_CRITICAL();

ptcb->OSTCBStkPtr=ptos;(3)

ptcb->OSTCBPrio=(INT8U)prio;

ptcb->OSTCBStat=OS_STAT_RDY;

ptcb->OSTCBDly=0;

#ifOS_TASK_CREATE_EXT_EN

ptcb->OSTCBExtPtr=pext;

ptcb->OSTCBStkSize=stk_size;

ptcb->OSTCBStkBottom=pbos;

ptcb->OSTCBOpt=opt;

ptcb->OSTCBId=id;

#else

pext=pext;

stk_size=stk_size;

pbos=pbos;

opt=opt;

id=id;

#endif

#ifOS_TASK_DEL_EN

ptcb->OSTCBDelReq=OS_NO_ERR;

#endif

ptcb->OSTCBY=prio>>3;

ptcb->OSTCBBitY=OSMapTbl[ptcb->OSTCBY];

ptcb->OSTCBX=prio0x07;

ptcb->OSTCBBitX=OSMapTbl[ptcb->OSTCBX];

#ifOS_MBOX_EN||(OS_Q_EN(OS_MAX_QS>=2))||OS_SEM_EN

ptcb->OSTCBEventPtr=(OS_EVENT*)0;

#endif

#ifOS_MBOX_EN||(OS_Q_EN(OS_MAX_QS>=2))

ptcb->OSTCBMsg=(void*)0;

#endif

OS_ENTER_CRITICAL();(4)

OSTCBPrioTbl[prio]=ptcb;(5)

ptcb->OSTCBNext=OSTCBList;

ptcb->OSTCBPrev=(OS_TCB*)0;

if(OSTCBList!=(OS_TCB*)0){

OSTCBList->OSTCBPrev=ptcb;

}

OSTCBList=ptcb;

OSRdyGrp|=ptcb->OSTCBBitY;(6)

OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;

OS_EXIT_CRITICAL();

return(OS_NO_ERR);(7)

}else{

OS_EXIT_CRITICAL();

return(OS_NO_MORE_TCB);

}

}

当OSTCBInit()需要将OS_TCB插入到已建立任务的OS_TCB的双向链表中时[L4.2(5)],它就禁止中断[L4.2(4)]。该双向链表开始于OSTCBList,而一个新任务的OS_TCB常常被插入到链表的表头。最后,该任务处于就绪状态[L4.2(6)],并且OSTCBInit()向它的调用者[OSTaskCreate()]返回一个代码表明OS_TCB已经被分配和初始化了[L4.2(7)]。

现在,我可以继续讨论OSTaskCreate()(程序清单 L4.1)函数了。从OSTCBInit()返回后,OSTaskCreate()要检验返回代码[L4.1(7)],如果成功,就增加OSTaskCtr[L4.1(8)],

OSTaskCtr用于保存产生的任务数目。 如果OSTCBInit()返回失败, 就置OSTCBPrioTbl[prio]

的入口为0[L4.1(12)]以放弃该任务的优先级。然后,OSTaskCreate()调用

OSTaskCreateHook()[L4.1(9)],OSTaskCreateHook()是用户自己定义的函数,用来扩展OSTaskCreate()的功能。例如,用户可以通过OSTaskCreateHook()函数来初始化和存储浮点寄存器、MMU寄存器的内容,或者其它与任务相关的内容。一般情况下,用户可以在内存中存储一些针对用户的应用程序的附加信息。OSTaskCreateHook()既可以在OS_CPU_C.C中定义(如果OS_CPU_HOOKS_EN置1),也可以在其它地方定义。注意,OSTaskCreate()在调用OSTaskCreateHook()时,中断是关掉的,所以用户应该使OSTaskCreateHook()函数中的代码尽量简化,因为这将直接影响中断的响应时间。OSTaskCreateHook()在被调用时会收到指向任务被建立时的OS_TCB的指针。 这意味着该函数可以访问OS_TCB数据结构中的所有成员。

如果OSTaskCreate()函数是在某个任务的执行过程中被调用(即OSRunning置为True[L4.1(10)]),则任务调度函数会被调用[L4.1(11)]来判断是否新建立的任务比原来的任务有更高的优先级。如果新任务的优先级更高,内核会进行一次从旧任务到新任务的任

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top