上一章我们学习了FreeRTOS的任务基础知识,本章就正式学习如何使用FreeRTOS中有关任务的API函数。本章想讲解FreeRTOS的任务原理知识的,但是很多初学者还没使用过FreeRTOS,甚至其他的RTOS系统都没有使用过,所以一上来就是苦涩的原理很可能会吓跑大批初学者。所以本章做了调整,先学习怎么用,先知其然,后面在知其所以然。使用过以后再学习原理、看源码就会轻松很多。

1、任务创建

【FreeRTOS】FreeRTOS学习笔记(4)— 任务创建、删除、挂起和恢复_宏定义

动态创建任务

#define TASK1_TASK_PRIO		1				//任务优先级
#define TASK1_STK_SIZE 		128  			//任务堆栈大小	
TaskHandle_t Task1Task_Handler;				//任务句柄
//动态创建一个任务1
xTaskCreate((TaskFunction_t )task1_task,            //任务函数  
            (const char*    )"task1_task",          //任务名称  
            (uint16_t       )TASK1_STK_SIZE,        //任务堆栈大小
            (void*          )NULL,                  //传递给任务函数的参数   
            (UBaseType_t    )TASK1_TASK_PRIO,       //任务优先级
            (TaskHandle_t*  )&Task1Task_Handler);   //任务句柄   

//task1任务函数
void task1_task(void *pvParameters)
{
	for(;;)
	{		
      vTaskDelay( 2000 );
	}
}

【FreeRTOS】FreeRTOS学习笔记(4)— 任务创建、删除、挂起和恢复_#define_02参数:

  • pxTaskCode:任务函数。
  • pcName:任务名字,一般用于追踪和调试,任务名字长度不能超过。configMAX_TASK_NAME_LEN,在FreeRTOSConfig.h文件中宏定义为16。
  • usStackDepth:任务堆栈大小,注意实际申请到的堆栈是usStackDepth的4倍。其中空闲任务的任务堆栈大小为configMINIMAL_STACK_SIZE,在FreeRTOSConfig.h文件中宏定义为130(字)。
  • pvParameters:传递给任务函数的参数。
  • uxPriority:任务优先级,范围0—configMAX_PRIORITIES-1,在FreeRTOSConfig.h文件中configMAX_PRIORITIES宏定义为32。
  • pxCreatedTask:任务句柄,任务创建成功以后会返回此任务的任务句柄,这个句柄其实就是任务的任务堆栈。此参数就用来保存这个任务句柄。其他API函数可能会使用到这个句柄。

返回值:

  • pdPASS:任务创建成功。pdPASS宏定义为1
  • errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:任务创建失败,因为堆内存不足!

静态创建任务

#define TASK1_TASK_PRIO					2		//任务优先级
#define TASK1_STK_SIZE 					128  	//任务堆栈大小	
StackType_t Task1TaskStack[TASK1_STK_SIZE];		//任务堆栈
StaticTask_t Task1TaskTCB;						//任务控制块
TaskHandle_t Task1Task_Handler;					//任务句柄
//静态创建一个任务1
Task1Task_Handler=xTaskCreateStatic((TaskFunction_t	)task1_task,		//任务函数
									(const char* 	)"task1_task",		//任务名称
									(uint32_t 		)TASK1_STK_SIZE,	//任务堆栈大小
									(void* 		  	)NULL,				//传递给任务函数的参数
									(UBaseType_t 	)TASK1_TASK_PRIO, 	//任务优先级
									(StackType_t*   )Task1TaskStack,	//任务堆栈
									(StaticTask_t*  )&Task1TaskTCB);	//任务控制块  
//task1任务函数
void task1_task(void *pvParameters)
{
	for(;;)
	{		
      vTaskDelay( 2000 );
	}
}

【FreeRTOS】FreeRTOS学习笔记(4)— 任务创建、删除、挂起和恢复_#define_03参数:

  • pxTaskCode:任务函数。
  • pcName:任务名字,一般用于追踪和调试,任务名字长度不能超过。configMAX_TASK_NAME_LEN,在FreeRTOSConfig.h文件中宏定义为16。
  • usStackDepth:任务堆栈大小,注意实际申请到的堆栈是usStackDepth的4倍。其中空闲任务的任务堆栈大小为configMINIMAL_STACK_SIZE,在FreeRTOSConfig.h文件中宏定义为130(字)。
  • pvParameters:传递给任务函数的参数。
  • uxPriority:任务优先级,范围0—configMAX_PRIORITIES-1,在FreeRTOSConfig.h文件中configMAX_PRIORITIES宏定义为32。
  • puxStackBuffer:任务堆栈,一般为数组,数组类型要为StackType_t类型(uint32_t)。
  • pxTaskBuffer:任务控制块,一般为结构体,结构体类型为StaticTask_t,在FreeRTOS.h中定义了这个结构体。

返回值:

  • NULL:任务创建失败,puxStackBufferpxTaskBufferNULL的时候会导致这个错误的发生。
  • 其他值任务创建成功,返回任务的任务句柄
2、任务删除

删除一个用函数xTaskCreate()或者xTaskCreateStatic()创建的任务,被删除了的任务不再存在,也就是说再也不会进入运行态。任务被删除以后就不能再使用此任务的句栖!如果此任务是使用动态方法创建的,也就是使用函数xTaskCreate()创建的,那么在此任务被删除以后此任务之前申请的堆栈和控制块内存会在空闲任务中被释放掉,因此当调用函数 xTaskCreate()删除任务以后必须给空闲任务一定的运行时间。

只有那些由内核分配给任务的内存才会在任务被删除以后自动的释放掉,用户分配给任务的内存需要用户自行释放掉,比如某个任务中用户调用函数pvPortMalloc()分配了500字节的内存,那么在此任务被删除以后用户也必须调用函数vPortFree()将这500字节的内存释放掉,否则会导致内存泄露。此函数原型如下

vTaskdelete(TaskHandle_t xTaskToDelete)

参数:

  • vTaskdelete:要删除的任务的任务句柄。

返回值:

3、任务挂起

有时候我们需要暂停某个任务的运行,过一段时间以后在重新运行。这个时候要是使用任务删除和重建的方法的话那么任务中变量保存的值肯定丢失了!Freertos给我们提供了解决这种问题的方法,那就是任务挂起和恢复,当某个任务要停止运行一段时间的话就将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行。

函数 描述
vTaskSuspend() 挂起一个任务
vTaskResume() 恢复一个任务的运行。
xTaskResumeFromISR() 中断服务函数中恢复一个任务的运行。

函数vTaskSuspend()

此函数用于将某个任务设置为挂起态,进入挂起态的任务永远都不会进入运行态。退出挂起态的唯一方法就是调用任务恢复函数 vTaskResume()或 xTaskResumeFromISR()。函数原型如下

void vTaskSuspend(TaskHandle_t xTaskToSusped)

参数:

  • xTaskToSuspend:要挂起的任务的任务句柄,创建任务的时候会为每个任务分配一个任务句柄。如果使用函数xTaskCreate()创建任务的话那么函数的参数pxCreatedTask就是此任务的任务句柄,如果使用函数xTaskCreateStatic()创建任务的话那么函数的返回值就是此任务的任务句柄。也可以通过函数xTaskGetHandle()来根据任务名字来获取某个任务的任务句柄。注意!如果参数为NULL的话表示挂起任务自己。

返回值:

4、任务恢复

1、函数vTaskResume()

将一个任务从挂起态恢复到就绪态,只有通过函数vTaskSuspend()设置为挂起态的任务才可以使用vTaskRexume()恢复!函数原型如下:

void vTaskResume(TaskHandle_t xTaskToresume)

参数:

  • xTaskToResume:要恢复的任务的任务句柄。

返回值:

2、函数 xTaskResumeFromISR()

此函数是vTaskResume()的中断版本,用于在中断服务函数中恢复一个任务。函数原型如下:

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume)

参数:

  • xTaskToResume:要恢复的任务的任务句柄。

返回值:

  • peTRUE:恢复运行的任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务),这意味着在退出中断服务函数以后必须进行一次上下文切换。
  • pdFALSE:恢复运行的任务的任务优先级低于当前正在运行的任务(被中断打断的任务),这意味着在退出中断服务函数的以后不需要进行上下文切换。