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、任务函数联系在一起。