本文写的是关于μc/os-III移植多任务配置的app.c文件的相关代码注释,大概的解释各程序段的作用
主要关注五个部分的配置,这也是移植时需要配置的五个部分。
static OS_TCB AppTaskStartTCB; //任务块起始后面的配置
static CPU_STK AppTaskStartStk[ APP_TASK_START_STK_SIZE]; //任务堆栈起始后面的配置
static void AppTaskStart (void *p_arg);//任务的起始,在其后声明我们的需要的任务
static void AppTaskStart (void *p_arg) {}//p_arg由函数OSTaskCreate()函数传递给AppTaskStart()
在上述函数里面,我们通过OSTaskCreate()函数来定义每个任务块的属性,包括:任务块起始地址、任务名称、任务代码起始地址、任务接收到的参数、任务优先级、任务栈空间基地址、任务栈深度、任务栈大小等等内容。具体的内容可以参考mian()里面的OSTaskCreate()函数,它们是一样的。
static void AppTaskLed1 ( void * p_arg ){}//诸如此类的几个,里面写的是任务的具体内容,函数的格式都是一致的,具体可以看程序代码
* Filename : app_cfg.h
* Version : V1.00
//注意:只包含了头文件的部分内容
/*定义三个LED任务的优先级*/
#define APP_TASK_LED1_PRIO 3u
#define APP_TASK_LED2_PRIO 3u //μc/os-III允许任务的优先级相同
#define APP_TASK_LED3_PRIO 3u
/*定义三个LED任务栈空间大小*/
#define APP_TASK_LED1_STK_SIZE 512u
#define APP_TASK_LED2_STK_SIZE 512u
#define APP_TASK_LED3_STK_SIZE 512u
* Filename : app.c
* Version : V1.00
#include <includes.h>
static OS_TCB AppTaskStartTCB;//声明起始任务块,给每一个任务控制块OS_TCB分配存储空间
/*声明相关的任务块*/
static OS_TCB AppTaskLed1TCB;//声明三个LED灯任务的OS_TCB任务控制块
static OS_TCB AppTaskLed2TCB;
static OS_TCB AppTaskLed3TCB;
static CPU_STK AppTaskStartStk[ APP_TASK_START_STK_SIZE]; //声明起始任务的堆栈
/*声明相关的任务堆栈*/
static CPU_STK AppTaskLed1Stk [ APP_TASK_LED1_STK_SIZE ];
static CPU_STK AppTaskLed2Stk [ APP_TASK_LED2_STK_SIZE ];
static CPU_STK AppTaskLed3Stk [ APP_TASK_LED3_STK_SIZE ];
static void AppTaskStart (void *p_arg); //声明起始任务函数
/*声明相关的任务函数*/
static void AppTaskLed1 ( void * p_arg );
static void AppTaskLed2 ( void * p_arg );
static void AppTaskLed3 ( void * p_arg );
int main (void) //主函数中创建和运行起始任务
{
OS_ERR err; //err是指向OS_ERR的变量,通过它返回错误码
OSInit(&err); //初始化uc/os系统
OSTaskCreate((OS_TCB *)&AppTaskStartTCB, //任务块的起始地址
(CPU_CHAR *)"App Task Start", //任务名称
(OS_TASK_PTR ) AppTaskStart, //任务代码的起始地址
(void *) 0, //任务接受到的参数
(OS_PRIO ) APP_TASK_START_PRIO, //任务优先级,数值小表示高优先级
(CPU_STK *)&AppTaskStartStk[0], // 任务栈空间的基地址,占空间的最低地址
(CPU_STK_SIZE) APP_TASK_START_STK_SIZE / 10, //任务栈的深度标志
(CPU_STK_SIZE) APP_TASK_START_STK_SIZE, //定义任务栈的大小,以CPU_STK的数目表示
(OS_MSG_QTY ) 5u, //
(OS_TICK ) 0u, //
(void *) 0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)&err); //指向接收错误的代码
OSStart(&err); //开始运行系统,及多任务处理
}
static void AppTaskStart (void *p_arg) //p_arg由函数OSTaskCreate()函数传递给AppTaskStart()
{
CPU_INT32U cpu_clk_freq;
CPU_INT32U cnts;
OS_ERR err;
(void)p_arg;
CPU_Init();//初始化μc/os
BSP_Init();//板级支持包,初始化板子上的硬件
cpu_clk_freq = BSP_CPU_ClkFreq(); //定义系统定时器的参照频率
cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz; //Determine nbr SysTick increments
OS_CPU_SysTickInit(cnts); //初始化系统时钟周期
Mem_Init(); //初始化内存管理模块
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageInit(&err); //Compute CPU capacity with no task running
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_IntDisMeasMaxCurReset();
#endif
//这里主要是任务的相关配置,配置的格式和主函数里的OSTaskCreate()一样,具体的内容含义参考上面主函数的配置
OSTaskCreate((OS_TCB *)&AppTaskLed1TCB, //Create the Led1 task
(CPU_CHAR *)"App Task Led1",
(OS_TASK_PTR ) AppTaskLed1,
(void *) 0,
(OS_PRIO ) APP_TASK_LED1_PRIO,
(CPU_STK *)&AppTaskLed1Stk[0],
(CPU_STK_SIZE) APP_TASK_LED1_STK_SIZE / 10,
(CPU_STK_SIZE) APP_TASK_LED1_STK_SIZE,
(OS_MSG_QTY ) 5u,
(OS_TICK ) 0u,
(void *) 0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)&err);
OSTaskCreate((OS_TCB *)&AppTaskLed2TCB, //Create the Led2 task
(CPU_CHAR *)"App Task Led2",
(OS_TASK_PTR ) AppTaskLed2,
(void *) 0,
(OS_PRIO ) APP_TASK_LED2_PRIO,
(CPU_STK *)&AppTaskLed2Stk[0],
(CPU_STK_SIZE) APP_TASK_LED2_STK_SIZE / 10,
(CPU_STK_SIZE) APP_TASK_LED2_STK_SIZE,
(OS_MSG_QTY ) 5u,
(OS_TICK ) 0u,
(void *) 0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)&err);
OSTaskCreate((OS_TCB *)&AppTaskLed3TCB, //Create the Led3 task
(CPU_CHAR *)"App Task Led3",
(OS_TASK_PTR ) AppTaskLed3,
(void *) 0,
(OS_PRIO ) APP_TASK_LED3_PRIO,
(CPU_STK *)&AppTaskLed3Stk[0],
(CPU_STK_SIZE) APP_TASK_LED3_STK_SIZE / 10,
(CPU_STK_SIZE) APP_TASK_LED3_STK_SIZE,
(OS_MSG_QTY ) 5u,
(OS_TICK ) 0u,
(void *) 0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)&err);
OSTaskDel ( & AppTaskStartTCB, & err) ; //删除自身任务的语句,立即执行,要想执行的任务都必须写在它的前面
/*如下是单任务的程序段,直接写在while里面了,没有专门创建任务块*/
/* while (DEF_TRUE) { //包含任务的具体内容,通常写成无限循环
LED1_TOGGLE ; //每隔5s切换一次LED1的亮灭状态
OSTimeDly ( 5000, OS_OPT_TIME_DLY, & err );*/
}
}
//任务的具体内容,通常写在无限循环里面
static void AppTaskLed1 ( void * p_arg )
{
OS_ERR err;
(void)p_arg;
while (DEF_TRUE) {
LED1_TOGGLE;
OSTimeDly ( 1000, OS_OPT_TIME_DLY, & err );
}
}
static void AppTaskLed2 ( void * p_arg )
{
OS_ERR err;
(void)p_arg;
while (DEF_TRUE) { //任务的具体内容,通常写在无限循环里面
LED2_TOGGLE;
OSTimeDly ( 5000, OS_OPT_TIME_DLY, & err );
}
}
static void AppTaskLed3 ( void * p_arg )
{
OS_ERR err;
(void)p_arg;
while (DEF_TRUE) { //任务的具体内容,通常写在无限循环里面
LED3_TOGGLE;
OSTimeDly ( 5000, OS_OPT_TIME_DLY, & err );
}
}