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

函数原型:

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:

任务2、3:

运行结果:

例程源码:

#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
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是UCOSIII操作系统任务创建、删除、挂起恢复的实验代码注解: ```c #include "includes.h" // UCOSIII头文件 // 任务堆栈大小 #define TASK_STACK_SIZE 512u // 任务优先级 #define TASK1_PRIO 1u #define TASK2_PRIO 2u // 任务堆栈空间 static CPU_STK Task1Stk[TASK_STACK_SIZE]; static CPU_STK Task2Stk[TASK_STACK_SIZE]; // 任务控制块 static OS_TCB Task1TCB; static OS_TCB Task2TCB; // 任务函数 static void Task1(void *p_arg); static void Task2(void *p_arg); int main(void) { OS_ERR err; // 初始化UCOSIII OSInit(&err); // 创建任务1 OSTaskCreate(&Task1TCB, // 任务控制块 "Task 1", // 任务名 Task1, // 任务函数 DEF_NULL, // 传递给任务函数的参数 TASK1_PRIO, // 任务优先级 &Task1Stk[0], // 任务堆栈起始地址 TASK_STACK_SIZE / 10u, // 任务堆栈大小 TASK_STACK_SIZE, // 任务堆栈空间 0u, // 任务扩展选项 OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR, // 任务选项 &err); // 创建任务2 OSTaskCreate(&Task2TCB, "Task 2", Task2, DEF_NULL, TASK2_PRIO, &Task2Stk[0], TASK_STACK_SIZE / 10u, TASK_STACK_SIZE, 0u, OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR, &err); // 启动UCOSIII内核 OSStart(&err); return 0; } // 任务1 static void Task1(void *p_arg) { OS_ERR err; while (DEF_TRUE) { // 执行任务1的操作 // ... // 挂起任务2 OSTaskSuspend(&Task2TCB, &err); // 恢复任务2 OSTaskResume(&Task2TCB, &err); // 删除任务2 OSTaskDel(&Task2TCB, &err); } } // 任务2 static void Task2(void *p_arg) { OS_ERR err; while (DEF_TRUE) { // 执行任务2的操作 // ... // 挂起任务1 OSTaskSuspend(&Task1TCB, &err); // 恢复任务1 OSTaskResume(&Task1TCB, &err); // 删除任务1 OSTaskDel(&Task1TCB, &err); } } ``` 代码中定义了两个任务,分别是`Task1`和`Task2`,并且设置了它们的优先级。在`main`函数中,首先调用`OSInit`函数初始化UCOSIII,然后调用`OSTaskCreate`函数创建任务1和任务2,最后调用`OSStart`函数启动UCOSIII内核。 在任务1和任务2的函数中,先执行一些操作,然后调用`OSTaskSuspend`函数挂起另一个任务,再调用`OSTaskResume`函数恢复另一个任务,最后调用`OSTaskDel`函数删除另一个任务。这样可以测试任务挂起恢复和删除功能。 需要注意的是,UCOSIII的任务堆栈是从高地址往低地址增长的,因此在创建任务时需要设置任务堆栈大小和任务堆栈空间,以及任务堆栈的起始地址。此外,还可以设置任务选项,例如`OS_OPT_TASK_STK_CHK`表示检查任务堆栈是否溢出,`OS_OPT_TASK_STK_CLR`表示在任务创建时清空任务堆栈。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值