UCOS操作系统——任务的挂起与恢复(四)

UCOS操作系统

前言

任务的删除是直接删除这个任务,以后都不在执行,但是我要是想等某一个状态触发了继续执行怎么办,这个时候就轮到任务的挂起与恢复发挥作用了。

一、任务挂起OSTaskSuspend()函数

有时候有些任务因为某些原因需要暂停运行,但是以后还要运行,因此我们就不能删除掉任务,这里我们可以使用 OSTaskSuspend()函数挂起这个任务,以后再恢复运行,函数OSTaskSuspend()的原型如下:

void OSTaskSuspend (OS_TCB *p_tcb,OS_ERR *p_err)

*p_tcb : 指向需要挂起的任务的 OS_TCB,可以通过指向一个 NULL 指针将调用该函数的任务挂起。
*p_err: 指向一个变量,用来保存该函数的错误码。
我们可以多次调用 OSTaskSuspend ()函数来挂起一个任务,因此我们需要调用同样次数的OSTaskResume()函数才可以恢复被挂起的任务,这一点非常重要。意思是挂起一次,然后需要解挂一次,你可以再次挂起,然后再次解挂。

二、任务恢复 OSTaskResume()函数

OSTaskResume()函数用来恢复被 OSTaskSuspend()函数挂起的任务,OSTaskResume()函数是唯一能恢复被挂起任务的函数。如果被挂起的任务还在等待别的内核对象,比如事件标志组、信号量、互斥信号量、消息队列等,即使使用 OSTaskResume()函数恢复了被挂起的任务,该任务也不一定能立即运行,该任务还是要等相应的内核对象,只有等到内核对象后才可以继续运行,OSTaskResume()函数原型如下:

void OSTaskResume (OS_TCB *p_tcb,OS_ERR *p_err)

*p_tcb : 指向需要解挂的任务的 OS_TCB,指向一个 NULL 指针是无效的,因为该任务正在运行,不需要解挂。
*p_err: 指向一个变量,用来保存该函数的错误码。

三、完整代码

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

//ÈÎÎñÓÅÏȼ¶
#define START_TASK_PRIO		3
//ÈÎÎñ¶ÑÕ»´óС	
#define START_STK_SIZE 		128
//ÈÎÎñ¿ØÖÆ¿é
OS_TCB StartTaskTCB;
//ÈÎÎñ¶ÑÕ»	
CPU_STK START_TASK_STK[START_STK_SIZE];
//ÈÎÎñº¯Êý
void start_task(void *p_arg);

//ÈÎÎñÓÅÏȼ¶
#define TASK1_TASK_PRIO		4
//ÈÎÎñ¶ÑÕ»´óС	
#define TASK1_STK_SIZE 		128
//ÈÎÎñ¿ØÖÆ¿é
OS_TCB Task1_TaskTCB;
//ÈÎÎñ¶ÑÕ»	
CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
void task1_task(void *p_arg);

//ÈÎÎñÓÅÏȼ¶
#define TASK2_TASK_PRIO		5
//ÈÎÎñ¶ÑÕ»´óС	
#define TASK2_STK_SIZE 		128
//ÈÎÎñ¿ØÖÆ¿é
OS_TCB Task2_TaskTCB;
//ÈÎÎñ¶ÑÕ»	
CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];
//ÈÎÎñº¯Êý
void task2_task(void *p_arg);

//LCDË¢ÆÁʱʹÓõÄÑÕÉ«
int lcd_discolor[14]={
    
    	WHITE, BLACK, BLUE,  BRED,      
						GRED,  GBLUE, RED,   MAGENTA,       	 
						GREEN, CYAN,  YELLOW,BROWN, 			
						BRRED, GRAY };

//Ö÷º¯Êý
int main(void)
{
    
    
	OS_ERR err;
	CPU_SR_ALLOC();
	
	delay_init();  //ʱÖÓ³õʼ»¯
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÖжϷÖ×éÅäÖÃ
	uart_init(115200);   //´®¿Ú³õʼ»¯
	LED_Init();         //LED³õʼ»¯	
	LCD_Init();			//LCD³õʼ»¯	
	
	POINT_COLOR = RED;
	LCD_ShowString(30,10,200,16,16,"ALIENTEK STM32F1");	
	LCD_ShowString(30,30,200,16,16,"UCOSIII Examp 6-2");
	LCD_ShowString(30,50,200,16,16,"Task Suspend and Resume");
	LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,90,200,16,16,"2015/3/19");
	
	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
}


//¿ªÊ¼ÈÎÎñÈÎÎñº¯Êý
void start_task(void *p_arg)
{
    
    
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;
	
	CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);  	//ͳ¼ÆÈÎÎñ                
#endif
	
#ifdef CPU_CFG_INT_DIS_MEAS_EN		//Èç¹ûʹÄÜÁ˲âÁ¿ÖжϹرÕʱ¼ä
    CPU_IntDisMeasMaxCurReset();	
#endif
	
#if	OS_CFG_SCHED_ROUND_ROBIN_EN  //µ±Ê¹ÓÃʱ¼äƬÂÖתµÄʱºò
	 //ʹÄÜʱ¼äƬÂÖתµ÷¶È¹¦ÄÜ,ʱ¼äƬ³¤¶ÈΪ1¸öϵͳʱÖÓ½ÚÅÄ£¬¼È1*5=5ms
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif
	
	OS_CRITICAL_ENTER();	//½øÈëÁÙ½çÇø
	//´´½¨TASK1ÈÎÎñ
	OSTaskCreate((OS_TCB 	* )&Task1_TaskTCB,		
				 (CPU_CHAR	* )"Task1 task", 		
                 (OS_TASK_PTR )task1_task, 			
                 (void		* )0,					
                 (OS_PRIO	  )TASK1_TASK_PRIO,     
                 (CPU_STK   * )&TASK1_TASK_STK[0],	
                 (CPU_STK_SIZE)TASK1_STK_SIZE/10,	
                 (CPU_STK_SIZE)TASK1_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )0,					
                 (void   	* )0,					
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR 	* )&err);				
				 
	//´´½¨TASK2ÈÎÎñ
	OSTaskCreate((OS_TCB 	* )&Task2_TaskTCB,		
				 (CPU_CHAR	* )"task2 task", 		
                 (OS_TASK_PTR )task2_task, 			
                 (void		* )0,					
                 (OS_PRIO	  )TASK2_TASK_PRIO,     	
                 (CPU_STK   * )&TASK2_TASK_STK[0],	
                 (CPU_STK_SIZE)TASK2_STK_SIZE/10,	
                 (CPU_STK_SIZE)TASK2_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )0,					
                 (void   	* )0,				
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, 
                 (OS_ERR 	* )&err);			 
	OS_CRITICAL_EXIT();	//Í˳öÁÙ½çÇø
	OSTaskDel((OS_TCB*)0,&err);	//ɾ³ýstart_taskÈÎÎñ×ÔÉí
}


//task1ÈÎÎñº¯Êý
void task1_task(void *p_arg)
{
    
    
	u8 task1_num=0;
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;
	
	POINT_COLOR = BLACK;
	OS_CRITICAL_ENTER();
	LCD_DrawRectangle(5,110,115,314); 	//»­Ò»¸ö¾ØÐÎ	
	LCD_DrawLine(5,130,115,130);		//»­Ïß
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
	OS_CRITICAL_EXIT();
	while(1)
	{
    
    
		task1_num++;	//ÈÎÎñ1Ö´ÐдÎÊý¼Ó1 ×¢Òâtask1_num1¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
		LED0= ~LED0;
		printf("ÈÎÎñ1ÒѾ­Ö´ÐУº%d´Î\r\n",task1_num);
		if(task1_num==5) 
		{
    
    
			OSTaskSuspend((OS_TCB*)&Task2_TaskTCB,&err);//ÈÎÎñ1Ö´ÐÐ5´Îºó¹ÒÆðÈÎÎñ2
			printf("ÈÎÎñ1¹ÒÆðÁËÈÎÎñ2!\r\n");
		}
		if(task1_num==10) 
		{
    
    
			OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err);	//ÈÎÎñ1ÔËÐÐ10´Îºó»Ö¸´ÈÎÎñ2
			printf("ÈÎÎñ1»Ö¸´ÁËÈÎÎñ2!\r\n");
		}
		LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //Ìî³äÇøÓò
		LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//ÏÔʾÈÎÎñÖ´ÐдÎÊý
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //ÑÓʱ1s
		
	}
}

//task2ÈÎÎñº¯Êý
void task2_task(void *p_arg)
{
    
    
	u8 task2_num=0;
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;
	
	POINT_COLOR = BLACK;
	OS_CRITICAL_ENTER();
	LCD_DrawRectangle(125,110,234,314); //»­Ò»¸ö¾ØÐÎ	
	LCD_DrawLine(125,130,234,130);		//»­Ïß
	POINT_COLOR = BLUE;
	LCD_ShowString(126,111,110,16,16,"Task2 Run:000");
	OS_CRITICAL_EXIT();
	while(1)
	{
    
    
		task2_num++;	//ÈÎÎñ2Ö´ÐдÎÊý¼Ó1 ×¢Òâtask1_num2¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
		LED1=~LED1;
		printf("ÈÎÎñ2ÒѾ­Ö´ÐУº%d´Î\r\n",task2_num);
		LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //ÏÔʾÈÎÎñÖ´ÐдÎÊý
		LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //Ìî³äÇøÓò
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //ÑÓʱ1s
	}
}


任务 1 运行 5 次后调用 OSTaskSuspend()函数挂起任务 2。当任务 1 运行到第 10 次就调用函数 OSTaskResume()函数解挂任务 2。

总结

学了FreeRTOS之后在学ucos感觉很简单,其实都是相同的,只是用的函数不一样。

猜你喜欢

转载自blog.csdn.net/qq_51963216/article/details/123884196