uC/OS-II源码分析(一)下载地址:它的特点:1)开源,2)可移植性,绝大部分代码用C写,硬件相关部分用汇编写,3可固化,4)可剪裁,这通过条件编译实现,使用#define语句定义所需要的功能。5)可剥夺性(总是运行就绪条件下优先级昀高的任务),6)多任务(可以管理64个任务,其中保留8个给uC/OS-II,因此用户昀多可有56个任务,每个任务优先级不同,也就意味着不支持时间片轮转调度法,因为这种方法适合于优先级平等的任务)。7)可确定性。函数调度和服务执行时间具有确定性,除了OSTimeTick()和某些事件标志服务,系统服务执行时间不依赖用户应用程序任务数目的多少。8)任务栈。允许每个任务自己单独的栈空间不同,可以使用栈空间检验函数确定所需要的栈空间大小。9)系统服务。提供信号量,互斥型信号量,事件标志,消息邮箱,消息队列,块大小固定的内存申请与释放,时间管理函数等服务。10)中断管理。中断嵌套层数昀多可达到255层。11)稳定性和可靠性。OSInit()函数用来初始化内核,必须首先调用。建立两个任务:空闲任务(其他任务都未就绪时运行),统计任务(计算CPU的利用率).******************************************************************Description:ThisfunctionisusedtoinitializetheinternalsofuC/OS-IIandMUSTbecalledpriortocreatinganyuC/OS-IIobjectand,priortocallingOSStart().*****************************************************************voidOSInit(void){OSInitHookBegin();/*调用用户特定的初始化代码(通过一个接口函数实现用户要求的插件式进入系统中)*/OS_InitMisc();/*初始化变量*/OS_InitRdyList();/*初始化就绪列表*/OS_InitTCBList();/*初始化OS_TCB空闲列表*/OS_InitEventList();/*初始化OS_EVENT空闲列表*/#if(OS_FLAG_EN0)&&(OS_MAX_FLAGS0)//允许事件标志OS_FlagInit();/*初始化事件标志结构*/#endif#if(OS_MEM_EN0)&&(OS_MAX_MEM_PART0)//允许内存管理OS_MemInit();/*初始化内存管理器*/#endif#if(OS_Q_EN0)&&(OS_MAX_QS0)//允许消息队列OS_QInit();/*初始化消息队列结构*/#endifOS_InitTaskIdle();/*创建空闲任务*/#ifOS_TASK_STAT_EN0OS_InitTaskStat();/*创建统计任务*/#endif#ifOS_TMR_EN0//允许时间管理OSTmr_Init();/*初始化时间管理器*/#endifOSInitHookEnd();/*调用用户特定的初始化代码(参考OSInitHookBegin())*/#ifOS_DEBUG_EN0//允许DebugOSDebugInit();//初始化调试器#endif}*********************************************************************************************Description:ThisfunctioniscalledbyOSInit()toinitializemiscellaneousvariables.********************************************************************************************staticvoidOS_InitMisc(void){#ifOS_TIME_GET_SET_EN0OSTime=0L;/*32位的系统时钟清零*/#endifOSIntNesting=0;/*中断嵌套层数计数器清零*/OSLockNesting=0;/*调度器锁的嵌套层数计数器清零*/OSTaskCtr=0;/*任务数清零*/OSRunning=OS_FALSE;/*指明多任务未开始*/OSCtxSwCtr=0;/*任务切换次数计数器清零*/OSIdleCtr=0L;/*32位空闲计数器清零*/#ifOS_TASK_STAT_EN0/*运行统计任务*/OSIdleCtrRun=0L;OSIdleCtrMax=0L;OSStatRdy=OS_FALSE;/*统计任务未就绪*/#endif}空闲任务和统计任务建立的代码基本一样,只是统计任务的优先级比空闲任务大1,*********************************************************************************************Description:ThisfunctioncreatestheIdleTask.********************************************************************************************staticvoidOS_InitTaskIdle(void){#ifOS_TASK_NAME_SIZE7//INT8Uerr;#endif#ifOS_TASK_CREATE_EXT_EN0//使用扩展的OSTaskCreateExt来创建#ifOS_STK_GROWTH==1//任务堆栈从底部向顶部增长的方向有两种:表示从大到小,表示从小到大(void)OSTaskCreateExt(OS_TaskIdle,(void*)0,/*没有参数传给OS_TaskIdle()*/&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE-1],/*设置堆栈顶*/OS_TASK_IDLE_PRIO,/*优先级设置为昀低*/OS_TASK_IDLE_ID,//设置ID&OSTaskIdleStk[0],/*设置栈底*/OS_TASK_IDLE_STK_SIZE,//设置栈大小(void*)0,/*没有TCB扩展数据结构OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);/*允许堆栈检测和清空堆栈*/#else(void)OSTaskCreateExt(OS_TaskIdle,(void*)0,/*NoargumentspassedtoOS_TaskIdle()*/&OSTaskIdleStk[0],/*SetTop-Of-StackOS_TASK_IDLE_PRIO,/*LowestprioritylevelOS_TASK_IDLE_ID,&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE-1],/*SetBottom-Of-Stack*/OS_TASK_IDLE_STK_SIZE,(void*)0,/*NoTCBextensionOS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);/*Enablestackchecking+clearstack*/#endif#else//使用不带扩展性的OSTaskCreate创建#ifOS_STK_GROWTH==1(void)OSTaskCreate(OS_TaskIdle,(void*)0,&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE-1],OS_TASK_IDLE_PRIO);#else(void)OSTaskCreate(OS_TaskIdle,(void*)0,&OSTaskIdleStk[0],OS_TASK_IDLE_PRIO);#endif#endif//设置任务名称#ifOS_TASK_NAME_SIZE14OSTaskNameSet(OS_TASK_IDLE_PRIO,(INT8U*)uC/OS-IIIdle,&err);#else#ifOS_TASK_NAME_SIZE7OSTaskNameSet(OS_TASK_IDLE_PRIO,(INT8U*)OS-Idle,&err);#endif#endif}uC/OS-II源码分析(二)在真正开始分析源代码前,先来看使用uC/OS-II的三个例子1)使用信号量#defineTASK_STK_SIZE512/*每个任务堆栈的大小(以字计算)*/#defineN_TASKS10/*任务数*/OS_STKTaskStk[N_TASKS][TASK_STK_SIZE];/*任务堆栈*/OS_STKTaskStartStk[TASK_STK_SIZE];//开始任务的堆栈charTaskData[N_TASKS];/*传给每个任务的数据*/OS_EVENT*RandomSem;//互斥型信号量voidmain(void){PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);/*清空屏幕*/OSInit();/*初始化uC/OS-II*/PC_DOSSaveReturn();/*保存环境以便稍后可以返回DOS环境*/PC_VectSet(uCOS,OSCtxSw);/*设置uC/OS-II的切换处理函数*/RandomSem=OSSemCreate(1);/*建立一个信号量*/OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);//创建第一个任务,优先级设置为昀大值OSStart();/*开始多任务*/}voidTaskStart(void*pdata){#ifOS_CRITICAL_METHOD==3/*为CPU的状态寄存器分配内存*/OS_CPU_SRcpu_sr;#endifchars[100];INT16Skey;pdata=pdata;/*这步是为了防止编译错误*/TaskStartDispInit();/*初始化显示屏*/OS_ENTER_CRITICAL();PC_VectSet(0x08,OSTickISR);/*替换机器的时钟中断函数为uC/OS-II所需要的中断函数*/PC_SetTickRate(OS_TICKS_PER_SEC);/*调整时钟频率*/OS_EXIT_CRITICAL();OSStatInit();/*初始化统计任务*/TaskStartCreateTasks();/*创建其他任务*/for(;;){TaskStartDisp();if(PC_GetKey(&key)==TRUE){/*是否按键*/if(key==0x1B){/*ESCAPE按下了*/PC_DOSReturn();/*返回DOS*/}}OSCtxSwCtr=0;/*切换次数计数器清零*/OSTimeDlyHMSM(0,0,1,0);/*挂起秒,让给其他任务运行*/}}staticvoidTaskStartCreateTasks(void){INT8Ui;for(i=0;iN_TASKS;i++){/*创建N_TASKS个任务*/TaskData[i]='0'+i;/*每个任务显示其数据*/OSTaskCreate(Task,(void*)&TaskData[i],&TaskStk[i][TASK_STK_SIZE-1],i+1);}}voidTask(void*pdata){INT8Ux;INT8Uy;INT8Uerr;for(;;){OSSemPend(RandomSem,0,&err);/*获取信号量*