μC/OS-II的任务管理
μ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)]来判断是否新建立的任务比原来的任务有更高的优先级。如果新任务的优先级更高,内核会进行一次从旧任务到新任务的任
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
