uC/OS-II源码分析(总体思路一)

文章转载地址:http://hi.baidu.com/zzz1367/blog/item/ae03dcd1b37a41d9562c84c3.html

首先从main函数开始,下面是uC/OS-II main函数的大致流程:

main(){

OSInit();

TaskCreate(...);

OSStart();

}

首先是调用OSInit进行初始化,然后使用TaskCreate创建几个进程/Task,最后调用OSStart,操作系统就开始运行了。

OSInit

最先看看OSInit完成哪些初始化:

void OSInit (void)

{

#if OS_VERSION >= 204

OSInitHookBegin();

#endif

OS_InitMisc();

OS_InitRdyList();

OS_InitTCBList();

OS_InitEventList();

#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)

OS_FlagInit();

#endif

#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)

OS_MemInit();

#endif

#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)

OS_QInit();

#endif

OS_InitTaskIdle();

#if OS_TASK_STAT_EN > 0

OS_InitTaskStat();

#endif

#if OS_VERSION >= 204

OSInitHookEnd();

#endif

#if OS_VERSION >= 270 && OS_DEBUG_EN > 0

OSDebugInit();

#endif

}

OS_InitMisc()完成的是一些其其他他的变量的初始化:

OSIntNesting = 0;

OSLockNesting = 0;

OSTaskCtr = 0;

OSRunning = FALSE;

OSCtxSwCtr = 0;

OSIdleCtr = 0L;

其中包括:中断嵌套标志OSIntNesting,调度锁定标志OSLockNesting,OS标志OSRunning等。OSRunning在这里设置为FALSE,在后面OSStartHighRdy中会被设置为TRUE表示OS开始工作。

OS_InitRdyList()初始化就绪Task列表:

static void OS_InitRdyList (void)

{

INT8U i;

INT8U *prdytbl;

OSRdyGrp = 0x00;

prdytbl = &OSRdyTbl[0];

for (i = 0; i < OS_RDY_TBL_SIZE; i++) {

*prdytbl++ = 0x00;

}

OSPrioCur = 0;

OSPrioHighRdy = 0;

OSTCBHighRdy = (OS_TCB *)0;

OSTCBCur = (OS_TCB *)0;

}

首先将OSRdyTbl[]数组中全部初始化0,同时将OSPrioCur/OSTCBCur初始化为0,OSPrioHighRdy/OSTCBHighRdy也初始化为0,这几个变量将在第一个OSSchedule中被赋予正确的值。

OS_InitTCBList()这个函数看名称我们就知道是初始化TCB列表。

static void OS_InitTCBList (void)

{

INT8U i;

OS_TCB *ptcb1;

OS_TCB *ptcb2;

OS_MemClr((INT8U *)&OSTCBTbl[0], sizeof(OSTCBTbl));

OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl));

ptcb1 = &OSTCBTbl[0];

ptcb2 = &OSTCBTbl[1];

for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) {

ptcb1->OSTCBNext = ptcb2;

#if OS_TASK_NAME_SIZE > 1

ptcb1->OSTCBTaskName[0] = '?';

ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL;

#endif

ptcb1++;

ptcb2++;

}

ptcb1->OSTCBNext = (OS_TCB *)0;

#if OS_TASK_NAME_SIZE > 1

ptcb1->OSTCBTaskName[0] = '?';

ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL;

#endif

OSTCBList = (OS_TCB *)0;

OSTCBFreeList = &OSTCBTbl[0];

}

这里完成的工作很简单,首先把整个数组使用OSTCBNext指针连接成链表链起来,然后将OSTCBList初始化为0,也就是还没有TCB,因为还没有Task产生,OSTCBFreeList指向OSTCBTbl[]数组的第一个表示所有TCB都处于Free状态。

OS_InitEventList()初始化Event列表。

static void OS_InitEventList (void)

{

#if OS_EVENT_EN && (OS_MAX_EVENTS > 0)

#if (OS_MAX_EVENTS > 1)

INT16U i;

OS_EVENT *pevent1;

OS_EVENT *pevent2;

OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl));

pevent1 = &OSEventTbl[0];

pevent2 = &OSEventTbl[1];

for (i = 0; i < (OS_MAX_EVENTS - 1); i++) {

pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;

pevent1->OSEventPtr = pevent2;

#if OS_EVENT_NAME_SIZE > 1

pevent1->OSEventName[0] = '?';

pevent1->OSEventName[1] = OS_ASCII_NUL;

#endif

pevent1++;

pevent2++;

}

pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;

pevent1->OSEventPtr = (OS_EVENT *)0;

#if OS_EVENT_NAME_SIZE > 1

pevent1->OSEventName[0] = '?';

pevent1->OSEventName[1] = OS_ASCII_NUL;

#endif

OSEventFreeList = &OSEventTbl[0];

#else

OSEventFreeList = &OSEventTbl[0];

OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED;

OSEventFreeList->OSEventPtr = (OS_EVENT *)0;

#if OS_EVENT_NAME_SIZE > 1

OSEventFreeList->OSEventName[0] = '?';

OSEventFreeList->OSEventName[1] = OS_ASCII_NUL;

#endif

#endif

#endif

}

同样将EventTbl[]数组中的OSEventType都初始化为OS_EVENT_TYPE_UNUSED。

OS_InitTaskIdle(),中间我们跳过其他的如Mem等的初始化,看看Idle Task的初始化。

(void)OSTaskCreateExt(OS_TaskIdle,

(void *)0,

&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1],

OS_IDLE_PRIO,

OS_TASK_IDLE_ID,

&OSTaskIdleStk[0],

OS_TASK_IDLE_STK_SIZE,

(void *)0,

OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

其实Idle Task的初始化很简单就是调用OSTaskCrete系列的函数创建一个Task, OSTaskCreate我们后面再做进一步分析。

初始化State Task也是类似调用OSTaskCreate系列函数创建Stat Task。这里只是创建了该Task的各个结构还没有真正运行该Task,直到OSStart中才依据优先级调度运行。

OK,到这里OSInit算高一个段落了,我们接着回到main往下看。

\SOFTWARE The main directory from the root where all software-related files are placed. \SOFTWARE\BLOCKS The main directory where all ‘Building Blocks’ are located. With μC/OS-II, I included a ‘building block’ that handles DOS-type compatible functions that are used by the example code. \SOFTWARE\BLOCKS\TO This directory contains the files for the TO utility (see Appendix E, TO). The source file is TO.C and is found in the \SOFTWARE\TO\SOURCE directory. The DOS executable file (TO.EXE) is found in the \SOFTWARE\TO\EXE directory. Note that TO requires a file called TO.TBL which must reside on your root directory. An example of TO.TBL is also found in the \SOFTWARE\TO\EXE directory. You will need to move TO.TBL to the root directory if you are to use TO.EXE. \SOFTWARE\uCOS-II The main directory where all μC/OS-II files are located. \SOFTWARE\uCOS-II\EX1_x86L This directory contains the source code for EXAMPLE #1 (see section 1.07, Example #1) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\EX2_x86L This directory contains the source code for EXAMPLE #2 (see section 1.08, Example #2) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\EX3_x86L This directory contains the source code for EXAMPLE #3 (see section 1.09, Example #3) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\Ix86L This directory contains the source code for the processor dependent code (a.k.a. the port) of μC/OS-II for an 80x86 Real-Mode, Large Model processor. \SOFTWARE\uCOS-II\SOURCE This directory contains the source code for processor independent portion of μC/OS-II. This code is fully portable to other processor architectures.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值