简介

本篇主要讲解任务的使用,包含任务的创建、删除、挂起、恢复。

任务创建和删除API

FreeRTOS 最基本的功能就是任务管理,而任务管理最基本的操作就是创建和删除任务。

动态创建任务

动态任务需要 RAM 来保存与任务有关的状态信息(任务控制块),任务也需要一定的 RAM 来作为任务堆栈。如果使用函数 xTaskCreate()来创建任务的话那么这些所需的 RAM 就会自动的从 FreeRTOS 的堆中分配,因此必须提供内存管理文件,默认我们使用heap_4.c这个内存管理文件,而且宏configSUPPORT_DYNAMIC_ALLOCATION 必须为1。 新创建的任务默认就是就绪态的,如果当前没有比它更高优先级的任务运行那么此任务就会立即进入运行态开始运行。不管在任务调度器启动前还是启动后,都可以创建任务。

  1. BaseType_t xTaskCreate(
  2. TaskFunction_t pxTaskCode,
  3. const char * const pcName,
  4. const uint16_t usStackDepth,
  5. void * const pvParameters,
  6. UBaseType_t uxPriority,
  7. TaskHandle_t * const pxCreatedTask )

参数

  • pxTaskCode: 任务函数。
  • pcName: 任务名字,一般用于追踪和调试,任务名字长度不能超过configMAX_TASK_NAME_LEN。
  • usStackDepth: 任务堆栈大小,注意实际申请到的堆栈是 usStackDepth 的 4 倍。
  • pvParameters: 传递给任务函数的参数。
  • uxPriotiry: 任务优先级,范围 0~ configMAX_PRIORITIES-1。
  • pxCreatedTask: 任务句柄,任务创建成功以后会返回此任务的任务句柄,这个句柄其实就是任务的任务堆栈。此参数就用来保存这个任务句柄。其他 API 函数可能会使用到这个句柄。

返回值

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

    静态任务创建

    静态创建的任务,内存空间是需要用户自己提供的。

    1. TaskHandle_t xTaskCreateStatic(
    2. TaskFunction_t pxTaskCode,
    3. const char * const pcName,
    4. const uint32_t ulStackDepth,
    5. void * const pvParameters,
    6. UBaseType_t uxPriority,
    7. StackType_t * const puxStackBuffer,
    8. StaticTask_t * const pxTaskBuffer )

    参数

  • pxTaskCode: 任务函数。

  • pcName: 任务名字,一般用于追踪和调试,任务名字长度不能超过configMAX_TASK_NAME_LEN。
  • usStackDepth: 任务堆栈大小,由于本函数是静态方法创建任务,所以任务堆栈由用户给出,一般是个数组,此参数就是这个数组的大小。
  • pvParameters: 传递给任务函数的参数。
  • uxPriotiry: 任务优先级,范围 0~ configMAX_PRIORITIES-1。
  • puxStackBuffer: 任务堆栈,一般为数组,数组类型要为 StackType_t 类型。
  • pxTaskBuffer: 任务控制块。

返回值

  • NULL: 任务创建失败,puxStackBuffer 或 pxTaskBuffer 为 NULL 的时候会导致这个错误的发生。
  • 其他值: 任务创建成功,返回任务的任务句柄。

创建受MPU保护的任务

创建受MPU保护的任务要求所使用的MCUMPU(内存保护单元),用此函数创建的任务会受到MPU的保护。

  1. BaseType_t xTaskCreateRestricted(
  2. const TaskParameters_t * const pxTaskDefinition,
  3. TaskHandle_t * pxCreatedTask )

参数

  • pxTaskDefinition: 指向一个结构体 TaskParameters_t,这个结构体描述了任务的任务函数、堆栈大小、优先级等。此结构体在文件 task.h 中有定义。
  • pxCreatedTask: 任务句柄。

返回值

  • pdPASS: 任务创建成功。
  • 其他值: 任务未创建成功,很有可能是因为 FreeRTOS 的堆太小了。

任务删除

删除了的任务不再存在,也就是说再也不会进入运行态。任务被删除以后就不能再使用此任务的句柄!如果此任务是使用动态方法创建的,也就是使用函数 xTaskCreate()创建的,那么在此任务被删除以后此任务之前申请的堆栈和控制块内存会在空闲任务中被释放掉,因此当调用函数 vTaskDelete()删除任务以后必须给空闲任务一定的运行时间。只有那些由内核分配给任务的内存才会在任务被删除以后自动的释放掉,用户分配给任务的内存需要用户自行释放掉。

  1. vTaskDelete( TaskHandle_t xTaskToDelete )

参数

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

返回值

任务挂起和恢复 API

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

挂起任务

进入挂起态的任务永远都不会进入运行态。

  1. void vTaskSuspend( TaskHandle_t xTaskToSuspend)

参数

  • xTaskToSuspend: 要挂起的任务的任务句柄。如果参数为 NULL 的话表示挂起任务自己。

返回值

任务级别的恢复任务

将一个任务从挂起态恢复到就绪态。这个函数只能在任务中调用。

  1. void vTaskResume( TaskHandle_t xTaskToResume)

参数

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

返回值

中断级别的任务恢复

将一个任务从挂起态恢复到就绪态。这个函数只能在中断中调用。

  1. BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume)

参数

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

返回值

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