天天看点

uC/OS-II任务的挂起和恢复

uCOS-II任务的挂起和恢复

文章转自:http://www.cnblogs.com/amanlikethis/p/4150452.html

函数描述

  1. OSTaskSuspend()

功能描述:无条件挂起一个任务。调用此函数的任务也可以传递参数OS_PRIO_SELF,挂起调用任务本身。

函数原型:INT8U OSTaskSuspend ( INT8U prio);

参数说明:prio为指定要获取挂起的任务优先级,也可以指定参数OS_PRIO_SELF,挂起任务本身。此时,下一个优先级最高的就绪任务将运行。

返回值:

OSTaskSuspend()的返回值为下述之一:

  • OS_NO_ERR:函数调用成功。
  • OS_TASK_ SUSPEND_IDLE:试图挂起μC/OS-II中的空闲任务(Idle task)。此为非法操作。
  • OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO或没有设定OS_PRIO_SELF的值。
  • OS_TASK_ SUSPEND _PRIO:要挂起的任务不存在。
  1. OSTaskResume()

功能描述:唤醒一个用OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。

函数原型:NT8U OSTaskResume ( INT8U prio)

参数说明:prio指定要唤醒任务的优先级

返回值:

OSTaskResume ()的返回值为下述之一:

  • OS_NO_ERR:函数调用成功。
  • OS_TASK_RESUME_PRIO:要唤醒的任务不存在。
  • OS_TASK_NOT_SUSPENDED:要唤醒的任务不在挂起状态。
  • OS_PRIO_INVALID:参数指定的优先级大于或等于

    OS_LOWEST_PRIO。

使用注意

当前任务挂起后,只有其他任务才能唤醒被挂起的任务。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数OSTaskResume()。 任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。

一个测试范例

测试平台:STM32

测试代码:

#define StartTaskPrio      4   
#define TASK1_PRIO         5  
#define TASK2_PRIO         6  

int main(void)
{
    USART1_Config();    
    OSInit();
    OSTaskCreate(StartTask, (void *)0, &StartTaskStk[StartTaskStkLength-1], StartTaskPrio);                     
    OSStart();
    return 0; 
}

void StartTask(void *p_arg)
{
    (void)p_arg;
    
    USART1_printf("\nStartTask has been running !");
    SysTick_Config(SystemCoreClock / OS_TICKS_PER_SEC);
    OSTaskCreate(Task1, (void *)0, &task1_stk[TASK1_STK_SIZE-1], TASK1_PRIO); 
    OSTaskCreate(Task2, (void *)0, &task2_stk[TASK2_STK_SIZE-1], TASK2_PRIO);  
    OSTaskSuspend(StartTaskPrio);
}

void Task1(void *p_arg)
{
    (void)p_arg; 

    while(1){    
        USART1_printf("\nTask1 has been running !");
        OSTaskSuspend(TASK1_PRIO);
    }
}

void Task2(void *p_arg)
{
    (void)p_arg; 

    while(1){
        USART1_printf("\n\nTask2 start running !");
        OSTaskResume(TASK1_PRIO); 
     USART1_printf("\nTask2 has been running !");                   
        OSTimeDly(2*OS_TICKS_PER_SEC);            
    }
}
           

程序执行时序流程:

uC/OS-II任务的挂起和恢复

运行结果:

uC/OS-II任务的挂起和恢复

增加

设计一个有两个任务MyTask和YourTask的应用程序,MyTask运行5次挂起自己,YourTask运行10次,为MyTask解挂;MyTask运行20次请求删除任务YourTask。要求写出完整代码

#include "includes.h"				//9
#define  TASK_STK_SIZE 512
OS_STK	MyTaskStk[TASK_STK_SIZE];
OS_STK	YourTaskStk[TASK_STK_SIZE];
INT16S	key;
INT8U	x = 0, y = 0;
INT8U	time_x	= 0, time_y = 0;
void MyTask( void *pdata );
void YourTask( void *pdata );
void  main( void ) {             //8
	char *s_M = "M";
	OSInit();
	PC_DOSSaveReturn();
	PC_VectSet( uCOS, OSCtxSw );
	OSTaskCreate( MyTask, s_M, &MyTaskStk[TASK_STK_SIZE - 1], 1 );
	OSStart();
}
void  MyTask( void *pdata ) {    		//36
	char *s_Y = "Y";
#if OS_CRITICAL_METHOD == 3
	OS_CPU_SR cpu_sr;
#endif

	pdata = pdata;

	OS_ENTER_CRITICAL();
	PC_VectSet( 0x08, OSTickISR );
	PC_SetTickRate( OS_TICKS_PER_SEC );
	OS_EXIT_CRITICAL();

	OSStatInit();
	OSTaskCreate( YourTask, s_Y, &YourTaskStk[TASK_STK_SIZE - 1], 2 );
	for (;; ) {
		if(time_x == 5) {
			OSTaskSuspend(OS_PRIO_SELF); 
		}
		if(time_x == 20) {
			while(OSTaskDelReq(2)!=OS_TASK_NOT_EXIST) {
				OSTimeDly(1);
			}
		}
		if ( x >= 10 ) {
			x	= 0;
			y	+= 2;
		}
		PC_DispChar( x, y, *(char *) pdata, DISP_BGND_BLACK + DISP_FGND_WHITE );
		x += 1;
		time_x += 1;
		if ( PC_GetKey( &key ) == TRUE ) {
			if ( key == 0x1B ) {
				PC_DOSReturn();
			}
		}
		OSTimeDlyHMSM( 0, 0, 1, 0 );
	}
}
void YourTask( void *pdata ) { 				//24
#if OS_CRITICAL_METHOD == 3
	OS_CPU_SR cpu_sr;
#endif
	pdata = pdata;
	for (;; ) {
		if(OSTaskDelReq(OS_PRIO_SELF)==OS_TASK_DEL_REQ) {  
			OSTaskDel(OS_PRIO_SELF);
		}
		else {
			if(time_y == 10) {
				OSTaskResume( 1 );
			}
			if ( x >= 10 ) {
				x	= 0;
				y	+= 2;
			}
			PC_DispChar( x, y, *(char *) pdata, DISP_BGND_BLACK + DISP_FGND_WHITE );
			x += 1;
			time_y += 1;
			OSTimeDlyHMSM( 0, 0, 1, 0 );
		}
	}
}

           

继续阅读