首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ucos在s3c2410上运行过程整体剖析-从main函数到UCOS初始化完毕(4)

ucos在s3c2410上运行过程整体剖析-从main函数到UCOS初始化完毕(4)

// 设计就绪表有两个目的:一,记录那些任务就绪。二,从这些就绪的任务中找出优先级最高的。就绪表是和任务调度有关系的数据结构,关于它的详细情况,在下面进行详细讲解。
static  void  OS_InitTCBList (void)
{
    INT8U    i;
    OS_TCB  *ptcb1;
    OS_TCB  *ptcb2;


OS_MemClr((INT8U *)&OSTCBTbl[0],sizeof(OSTCBTbl));/* Clear all the TCBs */  
//对任务控制块进行清零操作
OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl)); /* Clear the priority table */
// 对任务控制块优先级指针索引进行清零操作
    ptcb1 = &OSTCBTbl[0];
    ptcb2 = &OSTCBTbl[1];
    for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) {  /* Init. list of free TCBs            */
        ptcb1->OSTCBNext = ptcb2;
#if OS_TASK_NAME_SIZE > 1
        ptcb1->OSTCBTaskName[0] = '?'; /* Unknown name    */
        ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL;
#endif
        ptcb1++;
        ptcb2++;
}
//以上代码是把原来申请的TCB控制块的数组,链接成一个单向链表,这样有利于对TCB的操作。
ptcb1->OSTCBNext = (OS_TCB *)0;   /* Last OS_TCB */
//最后一个TCB的next指针指向空
#if OS_TASK_NAME_SIZE > 1
    ptcb1->OSTCBTaskName[0] = '?';  /* Unknown name */
    ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL;
#endif
OSTCBList  = (OS_TCB *)0;     /* TCB lists initializations          */
// OSTCBList 指向空,OSTCBList是创建后任务的任务控制块的头
OSTCBFreeList           = &OSTCBTbl[0];
//空闲任务控制块的链表头

}

我们对ucos初始化就是对ucos中的全局变量进行清零操作。在我们平时所写的程序里,可以动态分配内存,那是有操作系统的支持。现在我们写的是操作系统,因此不能用动态方式分配内存,ucos是这么做的,分配一些全局变量,然后为了好管理这些全局变量,我们把这些变量做成链表。当然我们申请的全局变量是结构体,结构体里有指向下一个结构体的指针,我们初始化只是把一些变量链接成链表的形式。

Ucos中对全局变量的初始化就这些,不好呀,突然出现这么多变量,都不知道他们是干什么的?他们之间有什么关系?这没事,我下面对这些变量以及他们的作用,和他们以后的用途,还有他们之间的关系做一个详细的说明。
主要分为以下几个核心部分:
1,  关于TCB的来龙去脉,一开始的逻辑结构以及到最后的逻辑结构。怎么说这个TCB是整个ucos的核心数据,用于控制任务的唯一数据。也是任务在ucos中存在的唯一标示。
2,  关于就绪表和任务调度
3,  其他几个核心变量的相关内容。

有了以上对这些数据的逻辑结构上的认识以及他们的作用,再加上前面咱们讲解的相关内容,我想我们在阅读源代码时就有了一定的思路。按照正常路线和中断路线两条路线去理解。

我们对这个TCB应该不陌生了,它是一个记录任务的相关信息的一个结构体。这个TCB空间一开始是程序通过数组的形式申请的全局变量存储空间,然后在ucos的初始化中做成一个单项链表,且它的链表头为OSTCBFreeList,当我们创建一个任务需要TCB时就从这个由TCB组成的线性链表上摘除一个,然后进行TCB的初始化,最后创建的任务的TCB连接成一个双向链表,且有一个以任务优先级为索引的TCB指针,这样设计数据结构的目的是方便通过优先级进行查找相应的TCB。
一开始,空闲TCB的状态如图:

当创建了几个任务之后TCB的状态如下:

我们先不看创建的任务是什么,而且这个图是从书上截取的,把这张图放到这个地方的原因是让我们知道OSTCBPrioTbl这个数组,以及TCB之间是怎样一种逻辑结构。OSTCBPrioTbl这个数组是一个索引数组,用于优先级的快速查找TCB。比如你知道一个优先级为3,那OSTCBPrioTbl[3]里的指针指向的就是优先级为3的任务控制块。那么再看这些TCB控制块是什么逻辑结构,这些控制块连接成双向链表,这个双向链表的头是OSTCBList。
对TCB 这个控制块的整体结构要有一个宏观的了解,这样我们看源码时才不会一头雾水,没有头绪。
关于就绪表,我要详细的说明。
就绪表是用于记录哪些任务是就绪状态的,创建就绪表的目的有两个:
1,  记录哪些任务是就绪态
2,  通过就绪表查找优先级最高的任务
继承事业,薪火相传
返回列表