任务创建 app.c代码讲解

任务创建 app.c代码讲解

任务创建步骤

1、定义任务控制块

第一步我们需要在app.c中为任务定义一个任务控制块,通常我们称这个任务控制块为任务的身份证。在 C 中上,任务控制块就是一个结构体,里面有非常多的成员,这些成员共同描述了任务的全部信息。

/*
*********************************************************************************************************
*                                                 TCB(任务控制块)
*********************************************************************************************************
*/
static  OS_TCB   AppTaskStartTCB;//声明起始任务块
/*声明用户自定义任务块*/
static  OS_TCB   AppTaskLed1TCB;
static  OS_TCB   AppTaskLed2TCB;

2、定义任务栈

任务的栈占用的是MCU 内部的 RAM,当任务越多的时候,需要使用的栈空间就越大,即需要使用的 RAM空间就越多。一个 MCU 能够支持多少任务,就得看你的 RAM 空间有多少。任务堆栈大小单位:如果 CPU_STK 被设置为CPU_INT08U,则单位为字节,而如果 CPU_STK 被设置为 CPU_INT16U,则单位为半字,同理,如果CPU_STK 被设置为 CPU_INT32U,单位为字。在 32 位的处理器下(STM32),一个字等于 4 个字节,那么任务大小就为 APP_TASK_START_STK_SIZE * 4 字节。代码如下:
例:AppTaskStart 任务和AppTaskLed1 任务以及AppTaskLed12任务
app_cfg.h

/*
*********************************************************************************************************
*                                           任务堆栈大小
*********************************************************************************************************
*/

#define  APP_TASK_START_STK_SIZE                    128
#define  APP_TASK_LED1_STK_SIZE                    512
#define  APP_TASK_LED2_STK_SIZE                    512

app.c:

/*
*********************************************************************************************************
*                                                STACKS(堆栈)
*********************************************************************************************************
*/

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];

3、定义任务主体函数

任务实际上就是一个无限循环且不带返回值的 C 函数。目前,我们可以如下格式创建一个这样的任务。
任务主体代码格式:

static void AppTaskLed1(void * p_arg)
{
  OS_ERR      err;
   (void)p_arg;
    while (DEF_TRUE) { //任务的具体内容,通常写在无限循环里面
			
		}
}

例程代码如下:
app.c中:

/*
*********************************************************************************************************
*                                         函数声明
*********************************************************************************************************
*/

static  void  AppTaskStart  (void *p_arg);
static  void  AppTaskLed1  (void *p_arg);
static  void  AppTaskLed2  (void *p_arg);

void main()
{

}
static void AppTaskLed1(void * p_arg)   //LED1 2.5s翻转一次
{
  OS_ERR      err;
   (void)p_arg;
    while (DEF_TRUE) { //任务的具体内容,通常写在无限循环里面
			LED1_TOGGLE;
			OSTimeDly ( 2500, OS_OPT_TIME_DLY, & err );
		}
}

static void AppTaskLed2(void * p_arg)  //LED2 5s翻转一次
{
   OS_ERR      err;
   (void)p_arg;
    while (DEF_TRUE) { //任务的具体内容,通常写在无限循环里面
			LED2_TOGGLE;
			OSTimeDly ( 5000, OS_OPT_TIME_DLY, & err );
		}
}

4、定义任务优先级

app_cfg.h:

/*
*********************************************************************************************************
*                                       TASK PRIORITIES  任务优先级
*********************************************************************************************************
*/
#define  APP_TASK_START_PRIO                        2

#define  APP_TASK_LED1_PRIO                         3
#define  APP_TASK_LED2_PRIO                         3

5、创建任务

uCOS 里面中通过任务创建函数 OSTaskCreate()将是任务主体函数,任务栈,任务控制块这三个要素联合在一起。让任务在创建之后可以随时被系统启动与调度。
app.c

 /*创建启动任务*/
    OSTaskCreate((OS_TCB     *)&AppTaskStartTCB,              //任务控制块
                 (CPU_CHAR   *)"App Task Start",              //任务名字  最好和任务入口函数名称一样
                 (OS_TASK_PTR ) AppTaskStart,                 //任务入口函数
/* 任务入口函数形参,不用的时候配置为 0 或者 NULL 即可,p_arg是指向可选数据区域的指针,用于将参数传递给任务,因为任务一旦执行,那必须是在一个死循环中,所以传参只在首次执行时有效。*/
                 (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,        //任务堆栈大小
                 (OS_MSG_QTY  ) 5u,                         //设置可以发送到任务的最大消息数,按需设置即可
                 (OS_TICK     ) 0u, //在任务之间循环时的时间片的时间量(以滴答为单位)指定 0则使用默认值。
                 (void       *) 0,  //是指向用户提供的内存位置的指针,用作 TCB 扩展
                 (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),   //用户可选的任务特定选项
                 (OS_ERR     *)&err);                        //用于保存返回的错误代码

用户可选的任务特定选项,具体见代码详情如下:

#define OS_OPT_TASK_NONE (OS_OPT)(0x0000u)         //未选择任何选项
#define OS_OPT_TASK_STK_CHK (OS_OPT)(0x0001u)      //启用任务的堆栈检查
#define OS_OPT_TASK_STK_CLR (OS_OPT)(0x0002u)      //任务创建时清除堆栈
#define OS_OPT_TASK_SAVE_FP (OS_OPT)(0x0004u)      //保存任何浮点寄存器的内容,这需要 CPU 硬件的支持
#define OS_OPT_TASK_NO_TLS (OS_OPT)(0x0008u)       //指定任务不需要 TLS 支持

通过 AppTaskStart ()任务创建任务

为了方便管理,用户自定义任务均在 AppTaskStart ( )中创建,main( )中只创建AppTaskStart()任务。AppTaskStart()代码如下:
app.c

static  void  AppTaskStart (void *p_arg)
{
    CPU_INT32U  cpu_clk_freq;
    CPU_INT32U  cnts;
    OS_ERR      err;
    
   (void)p_arg;

    BSP_Init();                                                //初始化函数                             
    CPU_Init();                                                //初始化UCOS
    cpu_clk_freq = BSP_CPU_ClkFreq();                          //定义SysTick系统定时器的参照频率                 
    cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz;       //定义 Systick 增量                     
    OS_CPU_SysTickInit(cnts);                                  // 初始化系统时钟周期            
    Mem_Init();                                                //初始化内存管理模块               
#if OS_CFG_STAT_TASK_EN > 0u
    OSStatTaskCPUUsageInit(&err);                              //计算CPU容量,不运行任何任务            
#endif
    CPU_IntDisMeasMaxCurReset();
    
    OSTaskCreate((OS_TCB     *)&AppTaskLed1TCB,                //创建LED1任务                               
                 (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,               // 创建LED2任务                             
                 (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);
	
   OSTaskDel(&AppTaskStartTCB ,& err );								 
}

二、app.c与app_cfg.h 相关代码

app_cfg.h(部分)

/*
*********************************************************************************************************
*                                               任务优先级
*********************************************************************************************************
*/
#define  APP_TASK_START_PRIO                        2
#define  APP_TASK_LED1_PRIO                         3
#define  APP_TASK_LED2_PRIO                         3
/*
*********************************************************************************************************
*                                           任务堆栈大小
*********************************************************************************************************
*/
#define  APP_TASK_START_STK_SIZE                    128
#define  APP_TASK_LED1_STK_SIZE                    512
#define  APP_TASK_LED2_STK_SIZE                    512

app.c(全部)

#include <includes.h>
/*
*********************************************************************************************************
*                                                 TCB(任务控制块)
*********************************************************************************************************
*/

static  OS_TCB   AppTaskStartTCB;
static  OS_TCB   AppTaskLed1TCB;
static  OS_TCB   AppTaskLed2TCB;

/*
*********************************************************************************************************
*                                                STACKS(堆栈)
*********************************************************************************************************
*/

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  void  AppTaskStart  (void *p_arg);
static  void  AppTaskLed1  (void *p_arg);
static  void  AppTaskLed2  (void *p_arg);

int  main (void)
{
    OS_ERR  err;
    OSInit(&err);                                          
    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,
                 (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)
{
    CPU_INT32U  cpu_clk_freq;
    CPU_INT32U  cnts;
    OS_ERR      err;
   (void)p_arg;

    BSP_Init();                                                
    CPU_Init();
    cpu_clk_freq = BSP_CPU_ClkFreq();                         
    cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz;        
    OS_CPU_SysTickInit(cnts);                                   
    Mem_Init();                                               
#if OS_CFG_STAT_TASK_EN > 0u
    OSStatTaskCPUUsageInit(&err);                               
#endif
    CPU_IntDisMeasMaxCurReset();

    OSTaskCreate((OS_TCB     *)&AppTaskLed1TCB,              
                 (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,                
                 (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);
	
   OSTaskDel(&AppTaskStartTCB ,& err );								 
}

static void AppTaskLed1(void * p_arg)
{
  OS_ERR      err;
   (void)p_arg;
    while (DEF_TRUE) { //任务的具体内容,通常写在无限循环里面
			LED1_TOGGLE;
			OSTimeDly ( 2500, 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 );
		}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值