赞
踩
目录
前面我们介绍了很多嵌入式相关的概念,任务的结构及相关的处理函数,本节内容我们主要看一下ucos的初始化流程以及任务的启动流程。
在使用ucos的所有服务之前,必须调用ucos的初始化函数 OSInit(),对ucos自身的运行环境进行初始化。
函数 OSInit()将对ucos的所有全局变量和数据结构进行初始化,同时创建空闲任务 OSTaskIdle,并赋之以最低的优先级别和永远的就绪状态。
如果用户应用程序还要使用统计任务(常数OS_ TASKSTATEN=1),则 OSInit()还要以优先级别为O_LOWESTPRIO-1来创建统计任务。
上图表示调用 OSInit()之后,一些μC/OS-Ⅱ变量和数据结构之间的关系。其解释是基于以下假设的:
以上两个任务的任务控制块(OS_TCBs)是用双向链表链接在一起的。OSTCBList 指向这个链表的起始处。当建立一个任务时,这个任务总是被放在这个链表的起始处。换句话说,OSTCBList 总是指向最后建立的那个任务。链的终点指向空字符 NULL(也就是零)。因为这两个任务都处在就绪态,在就绪任务表 OSRdyTbl[]中的相应位是设为 1 的。还有,因为这两个任务的相应位是在 OSRdyTbl[]的同一行上,即属同一组,故 OSRdyGrp 中只有 1 位是设为 1 的。
μC/OS-Ⅱ还初始化了 4 个空数据结构缓冲区,如上图所示。每个缓冲区都是单向链表,允许μC/OS-Ⅱ从缓冲区中迅速得到或释放一个缓冲区中的元素。注意,空任务控制块在空缓冲区中的数目取决于最多任务数 OS_MAX_TASKS,这个最多任务数是在 OS_CFG.H 文件中定义的。μC/OS-Ⅱ自动安排总的系统任务数 OS_N_SYS_TASKS(见文件μC/OS-Ⅱ.H)。控制块 OS_TCB 的数目也就自动确定了。
多任务的启动是用户通过调用 OSStart()实现的。然而,启动μC/OS-Ⅱ之前,用户至少要建立一个应用任务,如程序清单 所示。
程序清单初始化和启动μC/OS-Ⅱ
void main (void)
{
OSInit(); /* 初始化uC/OS-II */
通过调用OSTaskCreate()或OSTaskCreateExt()创建至少一个任务;
OSStart(); /* 开始多任务调度!OSStart()永远不会返回 */
}
OSStart()的代码如程序清单所示。当调用 OSStart()时,OSStart()从任务就绪表中找出那个用户建立的优先级最高任务的任务控制块。然后,OSStart()调用高优先级就绪任务启动函数 OSStartHighRdy(),OSStartHighRdy在多任务系统启动函数 OSStart()中调用。完成的功能是:设置系统运行标志位 OSRunning=TRUE,将就绪表中最高优先级任务的栈指针Load到SP中,并强制中断返回。这样就绪的最高优先级任务就如同从中断里返回到运行态一样,使得整个系统得以运转。
多任务启动以后变量与数据结构中的内容上图所示。这里假设用户建立的任务优先级为 6,注意,OSTaskCtr 指出已经建立了 3 个任务。OSRunning 已设为“真”,指出多任务已经开始,OSPrioCur 和 OSPrioHighRdy 存放的是用户应用任务的优先级,OSTCBCur和 OSTCBHighRdy 二者都指向用户任务的任务控制块。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。