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,负责创建任务2和任务3执行完任务函数后删除自身
- 任务2和任务3早任务运行的过程中,将自身运行次数通过串口打印PC端
- 任务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 } }