μC/OS-II的任务管理
务切换。如果在多任务调度开始之前(即用户还没有调用OSStart()),新任务就已经建立了,则任务调度函数不会被调用。 4.1建立任务,OSTaskCreateExt() 用OSTaskCreateExt()函数来建立任务会更加灵活,但会增加一些额外的开销。 OSTaskCreateExt()函数的代码如程序清单L4.3所示。 我们可以看到OSTaskCreateExt()需要九个参数!前四个参数(task,pdata,ptos和prio)与OSTaskCreate()的四个参数完全相同,连先后顺序都一样。这样做的目的是为了使用户能够更容易地将用户的程序从OSTaskCreate()移植到OSTaskCreateExt()上去。 id参数为要建立的任务创建一个特殊的标识符。 该参数在μC/OS以后的升级版本中可能会用到,但在μC/OS-Ⅱ中还未使用。这个标识符可以扩展μC/OS-Ⅱ功能,使它可以执行的任务数超过目前的64个。但在这里,用户只要简单地将任务的id设置成与任务的优先级一样的值就可以了。 pbos是指向任务的堆栈栈底的指针,用于堆栈的检验。 stk _size用于指定堆栈成员数目的容量。也就是说,如果堆栈的入口宽度为4字节宽,那么stk _size为10000是指堆栈有40000个字节。该参数与pbos一样,也用于堆栈的检验。 pext是指向用户附加的数据域的指针,用来扩展任务的OS_TCB。例如,用户可以为每个任务增加一个名字(参看实例3),或是在任务切换过程中将浮点寄存器的内容储存到这个附加数据域中,等等。 opt用于设定OSTaskCreateExt()的选项,指定是否允许堆栈检验,是否将堆栈清零,任务是否要进行浮点操作等等。 μCOS_Ⅱ.H文件中有一个所有可能选项(OS_TASK_OPT_STK_CHK,OS_TASK_OPT_STK_CLR和OS_TASK_OPT_SAVE_FP)的常数表。每个选项占有opt的一位, 并通过该位的置位来选定(用户在使用时只需要将以上OS_TASK_OPT_???选项常数进行位或(OR)操作就可以了)。 程序清单 L4.3 OSTaskCreateExt() INT8UOSTaskCreateExt(void(*task)(void*pd), void*pdata, OS_STK*ptos, INT8Uprio, INT16Uid, OS_STK*pbos, INT32Ustk_size, void*pext, INT16Uopt) { void*psp; INT8Uerr; INT16Ui; OS_STK*pfill; 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) if(optOS_TASK_OPT_STK_CHK){(5) if(optOS_TASK_OPT_STK_CLR){ Pfill=pbos; for(i=0;i #ifOS_STK_GROWTH==1 *pfill++=(OS_STK)0; #else *pfill--=(OS_STK)0; #endif } } } psp=(void*)OSTaskStkInit(task,pdata,ptos,opt);(6) err=OSTCBInit(prio,psp,pbos,id,stk_size,pext,opt);(7) if(err==OS_NO_ERR){(8) OS_ENTER_CRITICAL; OSTaskCtr++;(9) OSTaskCreateHook(OSTCBPrioTbl[prio]);(10) OS_EXIT_CRITICAL(); if(OSRunning){(11) OSSched();(12) } }else{ OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio]=(OS_TCB*)0;(13) OS_EXIT_CRITICAL(); } return(err); }else{ OS_EXIT_CRITICAL(); return(OS_PRIO_EXIST); } } OSTaskCreateExt()一开始先检测分配给任务的优先级是否有效[L4.3(1)]。 任务的优先级必须在0到OS_LOWEST_PRIO之间。接着,OSTaskCreateExt()要确保在规定的优先级上还没有建立任务[L4.3(2)]。在使用μC/OS-Ⅱ时,每个任务都有特定的优先级。如果某个优先级是空闲的,μC/OS-Ⅱ通过放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级[L4.3(3)]。这就使得OSTaskCreateExt()在设置任务数据结构的其他部分时能重新允许中断[L4.3(4)]。 为了对任务的堆栈进行检验[参看4.03,堆栈检验,OSTaskStkChk()],用户必须在opt参数中设置OS_TASK_OPT_STK_CHK标志。 堆栈检验还要求在任务建立时堆栈的存储内容都是0(即堆栈已被清零)。为了在任务建立的时候将堆栈清零,需要在opt参数中设置OS_TASK_OPT_STK_CLR。当以上两个标志都被设置好后,OSTaskCreateExt()才能将堆栈清零[L4.3(5)]。 接着,OSTaskCreateExt()调用OSTaskStkInit()[L4.3(6)],它负责建立任务的堆栈。该函数是与处理器的硬件体系相关的函数,可以在OS_CPU_C.C文件中找到。有关实现OSTaskStkInit()的细节可参看第八章——移植μC/OS-Ⅱ。如果已经有人在你用的处理器上成功地移植了μC/OS-Ⅱ,而你又得到了他的代码,就不必考虑该函数的实现细节了。 OSTaskStkInit()函数返回新的堆栈栈顶(psp),并被保存在任务的0S_TCB中。 μC/OS-Ⅱ支持的处理器的堆栈既可以从上(高地址)往下(低地址)递减也可以从下往上递增(参看4.02,任务堆栈)。用户在调用OSTa
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
