5.1 实现空闲任务
5.1.1 定义空闲任务栈
空闲任务栈在os_cfg_app.c(第一次使用os_cfg_app.c时需要自行在文件夹μC/OS-III\Source中新建并添加到工程的μC/OS-III Source组)文件中定义,具体参见代码清单5-1。
代码清单5-1 os_cfg_app.c文件
1 /* 2 ******************************************************************* 3 * 数据域 4 ******************************************************************* 5 */ 6 7 CPU_STK OSCfg_IdleTaskStk[OS_CFG_IDLE_TASK_STK_SIZE];(1) 8 9 10 11 /* 12 ******************************************************************* 13 * 常量 14 ******************************************************************* 15 */ 16 17 /* 空闲任务栈起始地址 */ 18 CPU_STK * const OSCfg_IdleTaskStkBasePtr = \(2) 19 (CPU_STK *)&OSCfg_IdleTaskStk[0]; 20 /* 空闲任务栈大小 */ 21 CPU_STK_SIZE const OSCfg_IdleTaskStkSize = \ 22 (CPU_STK_SIZE)OS_CFG_IDLE_TASK_STK_SIZE;
代码清单5-1(1):空闲任务栈是一个定义好的数组,大小由OS_CFG_IDLE_TASK_STK_SIZE这个宏控制。OS_CFG_IDLE_TASK_STK_SIZE在os_cfg_app.h头文件中定义,大小为128,具体参见代码清单5-2。
代码清单5-2 os_cfg_app.h文件
1 #ifndef OS_CFG_APP_H 2 #define OS_CFG_APP_H 3 4 /* 5 ******************************************************************* 6 * 常量 7 ******************************************************************* 8 */ 9 10 /* 空闲任务栈大小 */ 11 #define OS_CFG_IDLE_TASK_STK_SIZE 128u 12 13 #endif/* OS_CFG_APP_H */
代码清单5-1(2):空闲任务栈的起始地址和大小均被定义成一个常量,不能被修改。变量OSCfg_IdleTaskStkBasePtr和OSCfg_IdleTaskStkSize还在os.h中声明,这样就具有全局属性,可以在其他文件中调用,具体声明参见代码清单5-3。
代码清单5-3 OSCfg_IdleTaskStkBasePtr和OSCfg_IdleTaskStkSize声明
1 /* 空闲任务栈起始地址 */ 2 extern CPU_STK * const OSCfg_IdleTaskStkBasePtr; 3 /* 空闲任务栈大小 */ 4 extern CPU_STK_SIZE const OSCfg_IdleTaskStkSize;
5.1.2 定义空闲任务的任务控制块
任务控制块(TCB)是每一个任务必需的,空闲任务的TCB在os.h中定义,是一个全局变量,具体参见代码清单5-4。
代码清单5-4 定义空闲任务的TCB
/* 空闲任务的TCB */ 1 OS_EXT OS_TCB OSIdleTaskTCB;
5.1.3 定义空闲任务函数
空闲任务正如其名,空闲,任务体中只是对全局变量执行OSIdleTaskCtr ++操作,具体实现参见代码清单5-5。
代码清单5-5 空闲任务函数
1 /* 空闲任务 */ 2 void OS_IdleTask (void *p_arg) 3 { 4 p_arg = p_arg; 5 6 /* 空闲任务什么都不做,只对全局变量执行OSIdleTaskCtr++ 操作 */ 7 for (;;) { 8 OSIdleTaskCtr++; 9 } 10 }
代码清单5-5中的全局变量OSIdleTaskCtr在os.h中定义,具体参见代码清单5-6。
代码清单5-6 OSIdleTaskCtr定义
/* 空闲任务计数变量 */ 1 OS_EXT OS_IDLE_CTR OSIdleTaskCtr;
代码清单5-6中的OS_IDLE_CTR是在os_type.h中重新定义的数据类型,具体参见代码清单5-7。
代码清单5-7 OS_IDLE_CTR定义
/* 空闲任务计数变量定义 */ 1 typedef CPU_INT32U OS_IDLE_CTR;
5.1.4 空闲任务初始化
空闲任务的初始化用OSInit()函数完成,这意味着在系统还没有启动之前空闲任务就已经创建好,具体在os_core.c中定义,具体代码参见代码清单5-8。
代码清单5-8 空闲任务初始化函数
1 void OSInit (OS_ERR *p_err) 2 { 3 /* 配置操作系统初始状态为停止态 */ 4 OSRunning = OS_STATE_OS_STOPPED; 5 6 /* 初始化两个全局TCB,这两个TCB用于任务切换 */ 7 OSTCBCurPtr = (OS_TCB *)0; 8 OSTCBHighRdyPtr = (OS_TCB *)0; 9 10 /* 初始化就绪列表 */ 11 OS_RdyListInit(); 12 13 /* 初始化空闲任务 */ 14 OS_IdleTaskInit(p_err);(1) 15 if (*p_err != OS_ERR_NONE) { 16 return; 17 } 18 } 19 20 /* 空闲任务初始化 */ 21 void OS_IdleTaskInit(OS_ERR *p_err) 22 { 23 /* 初始化空闲任务计数器 */ 24 OSIdleTaskCtr = (OS_IDLE_CTR)0;(2) 25 26 /* 创建空闲任务 */ 27 OSTaskCreate( (OS_TCB *)&OSIdleTaskTCB,(3) 28 (OS_TASK_PTR )OS_IdleTask, 29 (void *)0, 30 (CPU_STK *)OSCfg_IdleTaskStkBasePtr, 31 (CPU_STK_SIZE)OSCfg_IdleTaskStkSize, 32 (OS_ERR *)p_err ); 33 }
代码清单5-8(1):空闲任务初始化函数在OSInit()中调用,在系统还没有启动之前就被创建。
代码清单5-8(2):初始化空闲任务计数器,这是预先在os.h中定义好的全局变量。
代码清单5-8(3):创建空闲任务,把栈、TCB、任务函数联系在一起。