uCOS-III多任务的创建

版权声明:本文为博主原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44880138/article/details/102731363

多任务创建的分类

1 万事具备只欠东风

在main函数中将硬件初始化,RTOS系统初始化,所有需要创建的任务都创建好,最后就是启动RTOS的调度器开始任务调度。

2 以一带多

在main函数中把硬件初始化,RTOS系统初始化好,然后创建一个启动任务,启动调度器,在这个启动任务中创建各种任务,在所有任务创建好之后,调用OSTaskDly()删除自身。

这两者没有很大的区别,但是我个人来说比较喜欢第二种,我觉得这样的代码更有模块化。

实验要求

LED1亮1s,LED2亮5秒,LED3亮10秒。它们的优先级都是3,启动任务的优先级是2。

头文件 app_cfg.h

//定义任务堆栈的大小
#define  APP_TASK_START_STK_SIZE                    128

#define  APP_TASK_LED1_STK_SIZE                   	512
#define  APP_TASK_LED2_STK_SIZE                    	512
#define  APP_TASK_LED3_STK_SIZE                   	512

//定义任务的优先级
#define  APP_TASK_START_PRIO                        2

#define  APP_TASK_LED1_PRIO                        	3
#define  APP_TASK_LED2_PRIO                        	3
#define  APP_TASK_LED3_PRIO                        	3

函数的主体app.c


#include "os.h"
#include "app_cfg.h"
#include "bsp.h"


static OS_TCB 		AppTaskStartTCB; //定义任务控制块

static OS_TCB 		AppTaskLED1TCB; //定义任务控制块LED1
static OS_TCB 		AppTaskLED2TCB; //定义任务控制块LED2
static OS_TCB 		AppTaskLED3TCB; //定义任务控制块LED3


/**定义任务堆栈**/
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 * parm);

static void AppTaskLED1(void * parm);
static void AppTaskLED2(void * parm);
static void AppTaskLED3(void * parm);



//启动函数的函数体
static void AppTaskStart(void * parm)
{
		OS_ERR err;// 错误的返回
	
		CPU_INT32U  cpu_clk_freq;
    CPU_INT32U  cnts;
	 
	   (void)parm;

		/* Initialize BSP functions   */
    BSP_Init();   
    CPU_Init();
		
		/* Determine SysTick reference freq. */
    cpu_clk_freq = BSP_CPU_ClkFreq();  

		/* Determine nbr SysTick increments  */
    cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz; 

	 /* Init uC/OS periodic time src (SysTick). */
    OS_CPU_SysTickInit(cnts);                                  

	 /* Initialize Memory Management Module  */
    Mem_Init();                                                

#if OS_CFG_STAT_TASK_EN > 0u
		 /* Compute CPU capacity with no task running */
    OSStatTaskCPUUsageInit(&err);                              
#endif

    CPU_IntDisMeasMaxCurReset();

	
	
	/**创建三个任务**/
	/*Tast LED1*/
	OSTaskCreate(		(OS_TCB     *)&AppTaskLED1TCB,/* Create the Led1 task */
                 (CPU_CHAR   *)"AppTaskLED1",
                 (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);
	
	/*Task LED2*/
	OSTaskCreate(		(OS_TCB     *)&AppTaskLED2TCB,/* Create the Led1 task */
                 (CPU_CHAR   *)"AppTaskLED2",
                 (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);
	/*Task LED3*/									
	OSTaskCreate(		(OS_TCB     *)&AppTaskLED3TCB,/* Create the Led1 task*/
                 (CPU_CHAR   *)"AppTaskLED3",
                 (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(0,&err);
	
}

int main(void)
{
	 OS_ERR err;
	 BSP_Init ();
	
	OSInit(&err); //初始化
	
	//创建启动任务
	OSTaskCreate((OS_TCB     *)&AppTaskStartTCB,/* Create the Led1 task */
                 (CPU_CHAR   *)"AppTaskStart",
                 (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); //启动任务,开调度	
}

/*Task LED1*/
static void AppTaskLED1(void * parm)
{
	OS_ERR err;
	(void )parm;
	
	while(1)
	{
		LED1_TOGGLE;
		OSTimeDly(1000,OS_OPT_TIME_DLY,&err);//实现毫秒级别的延时1000ms = 1s
	}
	
}

/*Task LED2*/
static void AppTaskLED2(void * parm)
{
		OS_ERR err;
	(void )parm;
	
	while(1)
	{
		LED2_TOGGLE;
		OSTimeDly(5000,OS_OPT_TIME_DLY,&err);
	}
}
/*Task LED3*/
static void AppTaskLED3(void * parm)
{
		OS_ERR err;
	(void )parm;
	
	while(1)
	{
		LED3_TOGGLE;
		OSTimeDly(10000,OS_OPT_TIME_DLY,&err);
	}
}


总结创建多任务和单任务没有大的区别
1 在main函数中创建一个启动任务。
2 在启动任务中创建三个任务,分别是用来启动LED1,LED2,LED3
3 在创建完三个任务后调用OSTaskDly()删掉启动任务。

uCOS-III的启动过程
1 上电复位后
2 执行Reset_Handle
3 执行__main
4 来到main (由汇编转入C语言的世界)

uCOS-III的任务是相互独立互不干扰的,各有各自独立的内存。

任务的数量是任意的(物理限制除外,内存的限制)。

可以多个任务具备同样的优先级,使用时间片轮转的方法调度。

任意时刻只有一个任务在执行(单核)。调度器永远是优先选择就绪态下优先级别最高的任务。

猜你喜欢

转载自blog.csdn.net/weixin_44880138/article/details/102731363