uCOSIII实时操作系统 五 任务API(任务创建和删除)

任务创建和删除

引入:一个任务的三要素是任务主体函数,任务栈,任务控制块,那么怎样吧这个三要素联系在一起呐?

任务创建:

在UCOSIII中我们通过函数OSTaskCreate()来创建任务。

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第1张图片

作用:任务控制块,任务堆栈,任务代码等联系在一起,并初始化控制块的相应字段。

位置:os_task.c中定义原型函数

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第2张图片

先不深究源码,先看看怎么用起来。

//任务创建函数入口参数解释
void  OSTaskCreate (OS_TCB        *p_tcb,//指向任务控制块OS_TCB
                    CPU_CHAR      *p_name,//指向任务的名字(字符串类型),每个任务都有不同的名字
                    OS_TASK_PTR    p_task,//执行任务代码,任务函数名
                    void          *p_arg,//传递任务主体函数的参数
                    OS_PRIO        prio,//任务优先级(一般从3开始,不用0/1/2)
                    CPU_STK       *p_stk_base,//指向堆栈基地址
                    CPU_STK_SIZE   stk_limit,//任务堆栈的最大深度(堆栈限制)
                    CPU_STK_SIZE   stk_size,//任务堆栈的大小
                    OS_MSG_QTY     q_size,//内嵌消息队列,0默认不用
                    OS_TICK        time_quanta,//时间片的长度,0默认时间节数除以10,// 轮转时间=time_quanta*时间长度
                    void          *p_ext,指向用户补充内存区,填0即可
                    OS_OPT         opt,//选项
                    /*选项:
                        OS_OPT_TASK_NONE //不使用任何选项
                        OS_OPT_TASK_STK_CHK //检查栈
                        OS_OPT_TASK_STK_CLR //清除栈
                        OS_OPT_TASK_SAVE_FP //保存浮点寄存器中的内容
                    */
                    OS_ERR        *p_err)//错误码

注意:为什么任务优先级一般从3开始

//UCOSIII中以下优先级用户程序不能使用,ALIENTEK
//将这些优先级分配给了UCOSIII的5个系统内部任务
//优先级0:中断服务服务管理任务 OS_IntQTask()
//优先级1:时钟节拍任务 OS_TickTask()
//优先级2:定时任务 OS_TmrTask()
//优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
//优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()

任务创建应用模版:

//任务优先级
#define START_TASK_PRIO		3
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈大小	
#define START_STK_SIZE 		512
//任务堆栈	
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);


int main(void)
{
	OS_ERR err;//定义一个错误码
	CPU_SR_ALLOC();//进入临界区,定义临界区需要的变量
	
//硬件初始化
/*
	delay_init();       //延时初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置
	uart_init(115200);    //串口波特率设置
	LED_Init();         //LED初始化
*/
	OSInit(&err);		//初始化UCOSIII
	OS_CRITICAL_ENTER();//进入临界区(关闭中断)
	//创建开始任务
/*
	OSTaskCreate((OS_TCB 	* )&StartTaskTCB,		//任务控制块
				 (CPU_CHAR	* )"start task", 		//任务名字
                 (OS_TASK_PTR )start_task, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )START_TASK_PRIO,     //任务优先级
                 (CPU_STK   * )&START_TASK_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)START_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)START_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err);				//存放该函数错误时的返回值
*/
	OS_CRITICAL_EXIT();	//退出临界区(开启中断)	 
	OSStart(&err);  //开启UCOSIII
	while(1);
}

任务删除:

OSTaskDel()函数用来删除当前任务。删除的任务将从所有就绪堵塞挂起和事件列表中删除。

作用: 用来删除任务,当一个任务不需要运行时候可以利用此函数删掉。  

位置:os_task.c中定义 函数原型:

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第3张图片

void  OSTaskDel (OS_TCB  *p_tcb,//删除任务TCB,也可以传递NULL指针删除自身函数
                 OS_ERR  *p_err)//返回错误码

eg:

OSTaskDel((OS_TCB*)0,&err); //删除任务自身 OSTaskDel((OS_TCB*)&Task2_TaskTCB,&err); //删除指定任务

任务创建和删除实验

实验要求:

1、主函数创建任务1负责创建任务2和任务3执行完函数之后删掉自身。
2、任务2和任务3在任务运行过程中要将自身运行次数通过串口打印。
3、任务2在执行任务超过十次后删除任务3

先准备一个移植好的空白模版:

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第4张图片

先定义一下任务1:

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第5张图片

在main函数当中根据之前的模版输入

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第6张图片

此时在创建任务1的各个入口参数与定义的任务1对应

编写任务1,因为要求我们在任务1中创建任务2任务3

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第7张图片

此时任务2任务3还未被定义,返回定义任务1的下方定义任务2任务3 :

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第8张图片

编写任务2任务3 函数。

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第9张图片

又裸机基础的上边要求的逻辑很好理解,这里就不在解释。

注意:在任务2/3都是运行在while(1)循环当中,要是任务一直在while(1)中没法挂起,退出死循环,那这样就不会进行任务3,所以while(1)中一定要加阻塞。所以用OSTimeDlyHMSM();函数进行延时阻塞。

这样实验就进行成功了查看一下运行结果:

uCOSIII实时操作系统 五 任务API(任务创建和删除)_第10张图片

实验源码:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "includes.h"

//UCOSIII中以下优先级用户程序不能使用,ALIENTEK
//将这些优先级分配给了UCOSIII的5个系统内部任务
//优先级0:中断服务服务管理任务 OS_IntQTask()
//优先级1:时钟节拍任务 OS_TickTask()
//优先级2:定时任务 OS_TmrTask()
//优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
//优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()

//创建任务1
//定义任务优先级
#define TASK_1_PRIO 3
//定义任务控制块
OS_TCB TASK_1_TCB;
//定义任务堆栈大小
#define TASK_1_STK_SIZE 128
//定义任务堆栈
CPU_STK TASK_1_STK[TASK_1_STK_SIZE];
//定义任务函数
void TASK_1(void *arg);

//创建任务2
//定义任务优先级
#define TASK_2_PRIO 4
//定义任务控制块
OS_TCB TASK_2_TCB;
//定义任务堆栈大小
#define TASK_2_STK_SIZE 128
//定义任务堆栈
CPU_STK TASK_2_STK[TASK_2_STK_SIZE];
//定义任务函数
void TASK_2(void *arg);

//创建任务3
//定义任务优先级
#define TASK_3_PRIO 5
//定义任务控制块
OS_TCB TASK_3_TCB;
//定义任务堆栈大小
#define TASK_3_STK_SIZE 128
//定义任务堆栈
CPU_STK TASK_3_STK[TASK_3_STK_SIZE];
//定义任务函数
void TASK_3(void *arg);


int main(void)
{
	OS_ERR err1;//错误码变量
	CPU_SR_ALLOC();//定义临界区需要的变量
	
	//硬件初始化
	delay_init();       //延时初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置
	uart_init(115200);    //串口波特率设置
	
	OSInit(&err1);//初始化UCOSIII
	OS_CRITICAL_ENTER();//进入临界区代码
	
	//创建开始任务1
	OSTaskCreate((OS_TCB 	* )&TASK_1_TCB,		//任务控制块
				 (CPU_CHAR	* )"main TASK1", 		//任务名字
                 (OS_TASK_PTR )TASK_1, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )TASK_1_PRIO,     //任务优先级
                 (CPU_STK   * )&TASK_1_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)TASK_1_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)TASK_1_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err1);				//存放该函数错误时的返回值
	
	OS_CRITICAL_EXIT();//退出临界区代码
	OSStart(&err1);//开启UCOSIII

	while(1);
}

void TASK_1(void *arg)
{
	OS_ERR err2_3;//错误码变量
	CPU_SR_ALLOC();//定义临界区需要的变量
	
	OS_CRITICAL_ENTER();//进入临界区代码
	
	//创建开始任务2
	OSTaskCreate((OS_TCB 	* )&TASK_2_TCB,		//任务控制块
				 (CPU_CHAR	* )"main TASK2", 		//任务名字
                 (OS_TASK_PTR )TASK_2, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )TASK_2_PRIO,     //任务优先级
                 (CPU_STK   * )&TASK_2_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)TASK_2_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)TASK_2_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err2_3);				//存放该函数错误时的返回值
	//创建开始任务3
	OSTaskCreate((OS_TCB 	* )&TASK_3_TCB,		//任务控制块
				 (CPU_CHAR	* )"main TASK3", 		//任务名字
                 (OS_TASK_PTR )TASK_3, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )TASK_3_PRIO,     //任务优先级
                 (CPU_STK   * )&TASK_3_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)TASK_3_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)TASK_3_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err2_3);				//存放该函数错误时的返回值							 
								 
	OS_CRITICAL_EXIT();//退出临界区代码
	
	//任务一执行完函数之后删掉自身
	OSTaskDel((OS_TCB *)0,&err2_3);			 
}


void TASK_2(void *arg)
{
	int num = 0;//任务2运行次数
	OS_ERR err2;
	while(1)
	{
		num++;
		if(num==10)
		{
			OSTaskDel((OS_TCB *)&TASK_3_TCB,&err2);
			printf("删除任务三\r\n");
		}
		printf("任务2运行次数:%d\r\n",num);
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err2);//延时1S
	}
}

void TASK_3(void *arg)
{
	int num = 0;//任务2运行次数
	OS_ERR err3;
	while(1)
	{
		num++;
		printf("任务3运行次数:%d\r\n",num);
		OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err3);//延时500ms
	}
}

 

  

你可能感兴趣的:(实时操作系统,实时操作系统,ucos,系统架构,C)