uC/OS-II源码分析(一)下载地址:http://www./ 它的特点: 1)开源, 2)可移植性,绝大部分代码用C写,硬件相关部分用汇编写, 3可固化, 4)可剪裁,这通过条件编译实现,使用#define语句定义所需要的功能。 5)可剥夺性(总是运行就绪条件下优先级最高的任务), 6)多任务(可以管理64个任务,其中保留8个给uC/OS-II,因此用户最多可有56个任务,每个任务优先级不同,也就意味着不支持时间片轮转调度法,因为这种方法适合于优先级平等的任务)。 7)可确定性。函数调度和服务执行时间具有确定性,除了OSTimeTick()和某些事件标志服务,系统服务执行时间不依赖用户应用程序任务数目的多少。 8)任务栈。允许每个任务自己单独的栈空间不同,可以使用栈空间检验函数确定所需要的栈空间大小。 9)系统服务。提供信号量,互斥型信号量,事件标志,消息邮箱,消息队列,块大小固定的内存申请与释放,时间管理函数等服务。 10)中断管理。中断嵌套层数最多可达到255层。 11)稳定性和可靠性。 OSInit()函数用来初始化内核,必须首先调用。建立两个任务:空闲任务(其他任务都未就绪时运行),统计任务(计算CPU的利用率). ***************************************************************** * Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to creating any uC/OS-II object and, prior to calling OSStart(). *****************************************************************
OSInit
void OSInit (void) { OSInitHookBegin(); /* 调用用户特定的初始化代码(通过一个接口函数实现用户要求的插件式进入系统中)*/ OS_InitMisc(); /* 初始化变量*/ OS_InitRdyList(); /* 初始化就绪列表*/ OS_InitTCBList(); /* 初始化OS_TCB空闲列表*/ OS_InitEventList(); /* 初始化OS_EVENT空闲列表*/ #if (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_TMR_EN > 0 //允许时间管理 OSTmr_Init(); /* 初始化时间管理器*/ #endif OSInitHookEnd(); /*调用用户特定的初始化代码(参考OSInitHookBegin())*/ #if OS_DEBUG_EN > 0 //允许Debug OSDebugInit(); //初始化调试器 #endif }
******************************************************************************************** * Description: This function is called by OSInit() to initialize miscellaneous variables. ******************************************************************************************** OS_InitMisc
static void OS_InitMisc (void) { #if OS_TIME_GET_SET_EN > 0 OSTime = 0L; /* 32位的系统时钟清零*/ #endif OSIntNesting = 0; /* 中断嵌套层数计数器清零*/ OSLockNesting = 0; /* 调度器锁的嵌套层数计数器清零*/ OSTaskCtr = 0; /* 任务数清零*/ OSRunning = OS_FALSE; /*指明多任务未开始*/ OSCtxSwCtr = 0; /* 任务切换次数计数器清零*/ OSIdleCtr = 0L; /*32位空闲计数器清零*/ #if OS_TASK_STAT_EN > 0 /*运行统计任务*/ OSIdleCtrRun = 0L; OSIdleCtrMax = 0L; OSStatRdy = OS_FALSE; /* 统计任务未就绪*/ #endif }
空闲任务和统计任务建立的代码基本一样,只是统计任务的优先级比空闲任务大1, ******************************************************************************************** * Description: This function creates the Idle Task. ******************************************************************************************** CodeOS_InitTaskIdle
static void OS_InitTaskIdle (void) { #if OS_TASK_NAME_SIZE > 7 // INT8U err; #endif #if OS_TASK_CREATE_EXT_EN > 0 //使用扩展的OSTaskCreateExt来创建 #if OS_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, /* No arguments passed to OS_TaskIdle() */ &OSTaskIdleStk[0], /* Set Top-Of-Stack OS_TASK_IDLE_PRIO, /* Lowest priority level OS_TASK_IDLE_ID, &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack */ OS_TASK_IDLE_STK_SIZE, (void *)0, /* No TCB extension OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */ #endif #else //使用不带扩展性的OSTaskCreate创建 #if OS_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 //设置任务名称 #if OS_TASK_NAME_SIZE > 14 OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"uC/OS-II Idle", &err); #else #if OS_TASK_NAME_SIZE > 7 OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"OS-Idle", &err); #endif #endif }
其他初始化代码放到后面具体的每一个子模块中再分析。 |
|