uCOSII源码详解.docx
- 文档编号:2921422
- 上传时间:2022-11-16
- 格式:DOCX
- 页数:17
- 大小:93.53KB
uCOSII源码详解.docx
《uCOSII源码详解.docx》由会员分享,可在线阅读,更多相关《uCOSII源码详解.docx(17页珍藏版)》请在冰豆网上搜索。
uCOSII源码详解
uC/OS-II源码分析(总体思路一)
首先从main函数开始,下面是uC/OS-IImain函数的大致流程:
main(){
OSInit();
TaskCreate(...);
OSStart();}
首先是调用OSInit进行初始化,然后使用TaskCreate创建几个进程/Task,最后调用OSStart,操作系统就开始运行了。
OSInit
最先看看OSInit完成哪些初始化:
voidOSInit(void)
{
#ifOS_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();
#ifOS_TASK_STAT_EN>0
OS_InitTaskStat();
#endif
#ifOS_VERSION>=204
OSInitHookEnd();
#endif
#ifOS_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列表:
staticvoidOS_InitRdyList(void)
{
INT8Ui;
INT8U*prdytbl;
OSRdyGrp=0x00;
prdytbl=&OSRdyTbl[0];
for(i=0;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列表。 staticvoidOS_InitTCBList(void) { INT8Ui; 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; #ifOS_TASK_NAME_SIZE>1 ptcb1->OSTCBTaskName[0]='? '; ptcb1->OSTCBTaskName[1]=OS_ASCII_NUL; #endif ptcb1++; ptcb2++; } ptcb1->OSTCBNext=(OS_TCB*)0; #ifOS_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列表。 staticvoidOS_InitEventList(void) { #ifOS_EVENT_EN&&(OS_MAX_EVENTS>0) #if(OS_MAX_EVENTS>1) INT16Ui; 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; #ifOS_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; #ifOS_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; #ifOS_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等的初始化,看看IdleTask的初始化。 (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); 其实IdleTask的初始化很简单就是调用OSTaskCrete系列的函数创建一个Task,OSTaskCreate我们后面再做进一步分析。 初始化StateTask也是类似调用OSTaskCreate系列函数创建StatTask。 这里只是创建了该Task的各个结构还没有真正运行该Task,直到OSStart中才依据优先级调度运行。 OK,到这里OSInit算高一个段落了,我们接着回到main往下看 uC/OS-II源码分析(总体思路二) OSTaskCreate负责创建Task所需的数据结构,该函数原形如下所示: INT8UOSTaskCreate(void(*task)(void*pd),void*p_arg,OS_STK*ptos,INT8Uprio) 其中task是一个函数指针,指向该Task所开始的函数,当这个Task第一次被调度运行时将会从task处开始运行。 p_arg是传给task的参数指针; ptos是堆栈指针,指向栈顶(堆栈从上往下)或栈底(堆栈从下往上); prio是进程的优先级,uC/OS-II共支持最大64个优先级,其中最低的两个优先级给Idle和Stat进程,并且各个Task的优先级必须不同。 接下来,我们看看这个函数的执行流程: #ifOS_ARG_CHK_EN>0 if(prio>OS_LOWEST_PRIO){ return(OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if(OSIntNesting>0){ OS_EXIT_CRITICAL(); return(OS_ERR_TASK_CREATE_ISR); } if(OSTCBPrioTbl[prio]==(OS_TCB*)0){ OSTCBPrioTbl[prio]=(OS_TCB*)1; OS_EXIT_CRITICAL(); psp=(OS_STK*)OSTaskStkInit(task,p_arg,ptos,0); err=OS_TCBInit(prio,psp,(OS_STK*)0,0,0,(void*)0,0); if(err==OS_NO_ERR){ if(OSRunning==TRUE){ OS_Sched(); } }else{ OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio]=(OS_TCB*)0; OS_EXIT_CRITICAL(); } return(err); } OS_EXIT_CRITICAL(); return(OS_PRIO_EXIST); OS_LOWEST_PRIO在ucos-ii.h中被定义为63,表示Task的优先级从0到63,共64级。 首先判断prio是否超过最低优先级,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- uCOSII 源码 详解
![提示](https://static.bdocx.com/images/bang_tan.gif)