ucos在s3c2410上运行过程整体剖析-从main函数到UCOS初始化完毕(4)
- UID
- 1029342
- 性别
- 男
|
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, 通过就绪表查找优先级最高的任务 |
|
|
|
|
|