在前面的章节中,笔者曾说过使命可所以一个无限的循环,也可所以在一次履行结束后被删去去。这儿要留意的是,使命代码并不是被真实的删去了,而仅仅μC/OS-Ⅱ不再理睬该使命代码,所以该使命代码不会再运行。使命看起来与任何C函数相同,具有一个回来类型和一个参数,仅仅它从不回来。使命的回来类型有必要被界说成void型。在本章中所说到的函数能够在OS_TASK文件中找到。如前所述,使命有必要是以下两种结构之一:
voidYourTask(void*pdata)
{
for(;;){
/* 用户代码 */
调用μC/OS-Ⅱ的服务例程之一:
OSMboxPend();
OSQPend();
OSSemPend();
OSTaskDel(OS_PRIO_SELF);
OSTaskSuspend(OS_PRIO_SELF);
OSTImeDly();
OSTimeDlyHMSM();
/* 用户代码 */
}
}
或
voidYourTask(void*pdata)
{
/* 用户代码 */
OSTaskDel(OS_PRIO_SELF);
}
本章所讲的内容包含怎么在用户的应用程序中树立使命、 删去使命、 改动使命的优先级、挂起和康复使命,以及取得有关使命的信息。
μC/OS-Ⅱ能够办理多达64个使命,并从中保存了四个最高优先级和四个最低优先级的使命供自己运用,所以用户能够运用的只要56个使命。使命的优先级越高,反映优先级的值则越低。在最新的μC/OS-Ⅱ版别中,使命的优先级数也可作为使命的标识符运用。
4.0 树立使命,OSTaskCreate()
想让μC/OS-Ⅱ办理用户的使命,用户有必要要先树立使命。用户能够经过传递使命地址和其它参数到以下两个函数之一来树立使命:OSTaskCreate()或OSTaskCreateExt()。
OSTaskCreate()与μC/OS是向下兼容的, OSTaskCreateExt()是 OSTaskCreate()的扩展版别,供给了一些附加的功用。用两个函数中的任何一个都能够树立使命。使命能够在多使命调度开端前树立,也能够在其它使命的履行进程中被树立。在开端多使命调度(即调用OSStart())前,用户有必要树立至少一个使命。使命不能由中止服务程序(ISR)来树立。
OSTaskCreate()的代码如程序清单L4.1所述。从中能够知道,OSTaskCreate()需求四个参数: task是使命代码的指针, pdata是当使命开端履行时传递给使命的参数的指针, ptos是分配给使命的仓库的栈顶指针(参看4.02,使命仓库),prio是分配给使命的优先级。
程序清单 L4.1 OSTaskCreate()
INT8UOSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,
INT8Uprio)
{
void*psp;
INT8Uerr;
if(prio>OS_LOWEST_PRIO){(1)
return(OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
if(OSTCBPrioTbl[prio]==(OS_TCB*)0){(2)
OSTCBPrioTbl[prio]=(OS_TCB*)1;(3)
OS_EXIT_CRITICAL();(4)
psp=(void*)OSTaskStkInit(task,pdata,ptos,0);(5)
err=OSTCBInit(prio,psp,(void*)0,0,0,(void*)0,0);(6)
if(err==OS_NO_ERR){(7)
OS_ENTER_CRITICAL();
OSTaskCtr++;(8)
OSTaskCreateHook(OSTCBPrioTbl[prio]);(9)
OS_EXIT_CRITICAL();
if(OSRunning){(10)
OSSched();(11)
}
}else{
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio]=(OS_TCB*)0;(12)
OS_EXIT_CRITICAL();
}
return(err);
}else{
OS_EXIT_CRITICAL();
return(OS_PRIO_EXIST);
}
}
OSTaskCreate()一开端先检测分配给使命的优先级是否有用[L4.1(1)]。使命的优先级有必要在0到OS_LOWEST_PRIO之间。接着,OSTaskCreate()要保证在规则的优先级上还没有树立使命[L4.1(2)]。在运用μC/OS-Ⅱ时,每个使命都有特定的优先级。假如某个优先级是闲暇的,μC/OS-Ⅱ经过放置一个非空指针在OSTCBPrioTbl[]中来保存该优先级[L4.1(3)]。
这就使得OSTaskCreate()在设置使命数据结构的其他部分时能从头答应中止[L4.1(4)]。然后,OSTaskCreate()调用OSTaskStkInit()[L4.1(5)],它担任树立使命的仓库。该函数是与处理器的硬件系统相关的函数,能够在OS_CPU_C.C文件中找到。有关完成OSTaskStkInit()的细节可参看第8章——移植μC/OS-Ⅱ。假如现已有人在你用的处理器上成功地移植了μC/OS-Ⅱ,而你又得到了他的代码,就不必考虑该函数的完成细节了。
OSTaskStkInit()函数回来新的仓库栈顶(psp),并被保存在使命的0S_TCB中。 留意用户得将传递给OSTaskStkInit()函数的第四个参数opt置0,由于OSTaskCreate()与OSTaskCreateExt()不同,它不支撑用户为使命的创立进程设置不同的选项,所以没有任何选项能够经过opt参数传递给OSTaskStkInit()。
μ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)