uC/OS-II任务管理:
µC/OS-Ⅱ可以管理多达 64 个任务,并从中保留了四个最高优先级和四个最低优先级的任务供自己使用,所以用户可以使用的只有 56 个任务。任务的优先级越高,反映优先级的值则越低。
任务的创建:OSTaskCreate()和OSTaskCreateExt()
OSTaskCreateExt()是 OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中被建立。 在开始多任务调度(即调用 OSStart())前,用户必须建立至少一个任务。任务不能由中断服务程序(ISR)来建立。
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
参数:task:任务函数指针,pdata:任务开始执行时传递给任务的参数的指针,ptos:分配给任务的堆栈的栈顶指针,prio:分配给任务的优先级
任务堆栈:
每个任务都有自己的堆栈空间。堆栈必须声明为 OS_STK 类型,并且由连续的内存空间组成。用户可以静态分配堆栈空间(在编译的时候分配)也可以动态地分配堆栈空间(在运行的时候分配)。
用户可以用 C 编译器提供的 malloc()函数来动态地分配堆栈空间,在动态分配中,用户要时刻注意内存碎片问题。特别是当用户反复地建立和删除任务时,内存堆中可能会出现大量的内存碎片,导致没有足够大的一块连续内存区域可用作任务堆栈,这时 malloc()便无法成功地为任务分配堆栈空间。
堆栈从下往上递增:
当 OS_CPU.H 文件中的 OS_STK_GROWTH 置为 0 时,用户需要将堆栈的最低内存地址传递给任务创建函数,如下程序所示。
OS_STK TaskStack[TASK_STACK_SIZE];
OSTaskCreate(task, pdata, &TaskStack[0], prio);
堆栈从上往下递减:
当 OS_CPU.H 文件中的 OS_STK_GROWTH 置为 1 时,用户需要将堆栈的最高内存地址传递给任务创建函数,如下程序所示。
OS_STK TaskStack[TASK_STACK_SIZE];
OSTaskCreate(task, pdata, &TaskStack[TASK_STACK_SIZE-1], prio);
对两个方向增长的堆栈都提供支持:
OS_STK TaskStack[TASK_STACK_SIZE];
#if OS_STK_GROWTH == 0
OSTaskCreate(task, pdata, &TaskStack[0], prio);
#else
OSTaskCreate(task, pdata, &TaskStack[TASK_STACK_SIZE-1], prio);
#endif
任务所需的堆栈的容量是由应用程序指定的。用户在指定堆栈大小的时候必须考虑用户的任务所调用的所有函数的嵌套情况,任务所调用的所有函数会分配的局部变量的数目,以及所有可能的中断服务例程嵌套的堆栈需求。另外,用户的堆栈必须能储存所有的 CPU 寄存器。
堆栈检验:主要用于计算任务实际使用的栈空间大小和空闲的栈空间大小,并把有关任务堆栈的信息存在OS_STK_DATA结构中。
删除任务:
OSTaskDel(INT8U prio)不安全,可能会导致任务占用的资源没有释放。
OSTaskDelReq(INT8U prio)该函数通过任务控制块中的OSTCBDelReq作为请求删除方和被删除方的联络信号。
改变任务的优先级:OSTaskChangePrio()
挂起任务:OSTaskSuspend()
有时候将任务挂起是很有用的。挂起任务可通过调用 OSTaskSuspend()函数来完成。被挂起的任务只能通过调用 OSTaskResume()函数来恢复。
恢复任务:OSTaskResume()
OSTaskResume()是通过清除 OSTCBStat 域中的OS_STAT_SUSPEND 位来取消挂起的。要使任务处于就绪状态,OS_TCBDly 域必须为 0,这是因为在 OSTCBStat 中没有任何标志表明任务正在等待延时的期满。只有当以上两个条件都满足的时候,任务才处于就绪状态。最后,任务调度程序会检查被恢复的任务拥有的优先级是否比调用本函数的任务的优先级高。
获得有关任务的信息:OSTaskQuery()
实际上,OSTaskQuery()获得的是对应任务的 OS_TCB 中内容的拷贝。