uCOSIII实时操作系统 五 任务API(任务挂起与恢复)

任务挂起和恢复

任务挂起:

OSTaskSuspend()将任务阻塞,也就是被剥夺CPU的使用权而暂时终止运行,转到阻塞状态,OSTaskSuspend()将任务转到阻塞态被挂起称为任务挂起。被挂起的任务得不到CPU的使用权,也不会参与调度,它相对于调度器而言是看不见的,除非他从挂起态中解除。

注意:  被挂起的任务不能运行,直到其他任务以该优先级作为参数调用OSTaskResume()来恢复他,才能将该任务的状态重新设置为就绪状态。

OSTaskSuspend()函数作用:因某些原因暂停运行,但以后还要运行,此函数挂起。

位置:os_task.c       函数原型:

void   OSTaskSuspend (OS_TCB  *p_tcb,//挂起指定控制块,可以通过NULL挂起自身
                      OS_ERR  *p_err)//保存该函数的错误码

注意:任务的挂起与恢复函数在很多时候都是很有用的,比如我们想暂停某个任务运行一段时间,但是我们又需要在其恢复的时候继续工作,因为删除了任务的话,任务的所有信息都是不可能恢复的了,删除是完完全全删除了,里边的资源都会被系统释放掉,而调用挂起任务函数的时候,任务进入挂起态,其内部的资源都会保留下来,同时也不会参加任务调度,当调用恢复函数的时候,整个任务立即从挂起状态进入就绪状态,并且参与任务的调度,如果当前任务优先级是当前就绪态优先级最高的任务,那么立刻就会按照挂起前的任务状态继续执行该任务,

任务恢复:

OSTaskResume()函数作用:把挂起任务恢复

位置:os_task.c

uCOSIII实时操作系统 五 任务API(任务挂起与恢复)_第1张图片

函数原型:

void  OSTaskResume (OS_TCB  *p_tcb,//恢复指定的任务块,可以通过NULL恢复自身
                    OS_ERR  *p_err)//保存该函数的错误码

实例:OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err);//恢复指定任务Task2_TaskTCB
            OSTaskResume((OS_TCB*)0,&err);//恢复自身任务

注意:OSTaskResume() 函数用于恢复挂起的任务。任务在挂起时候调用过多少次OS_TaskSuspend() 函数,那么就需要调用多少次 OSTaskResume() 函数才能将任务恢复运行。

任务的挂起与恢复实验:

实验要求:

  1. 主函数中创建任务1,负责创建任务2和任务3执行完任务函数后删除自身
  2. 任务2和任务3早任务运行的过程中,将自身运行次数通过串口打印PC端
  3. 任务2在执行任务10次后将任务3挂起,在执行任务2 15次后恢复运行。

此实验在上篇博客http://t.csdnimg.cn/yYrxq的基础上建立

任务1:

uCOSIII实时操作系统 五 任务API(任务挂起与恢复)_第2张图片

任务2、3:

uCOSIII实时操作系统 五 任务API(任务挂起与恢复)_第3张图片

运行结果:

uCOSIII实时操作系统 五 任务API(任务挂起与恢复)_第4张图片

例程源码:

#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(10==num)
		{
			OSTaskSuspend((OS_TCB *)&TASK_3_TCB,&err2);
			printf("挂起任务三\r\n");
		}
		else if(15==num)
		{
			OSTaskResume((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,实时操作系统)