四 freertos任务管理
一 任务创建函数
使用函数: xTaskCreate 用于任务的创建,并且还可以自定义任务栈的大小。
函数原型:
BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode,
const char * const pcName,
unsigned short usStackDepth,
void * pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * pvCreatedTask
);
参数描述: ——pvTaskCode : 第 1 个参数填创建任务的函数名。 ——pcName: 第 2 个参数是任务名,这个参数主要是用于调试目的,调试的时候方便看是哪个任务。 —— usStackDepth: 第 3 个参数是任务栈大小,单位 word,也就是 4 字节。 —— pvParameters: 第 4 个参数是创建的任务函数的形参。 —— uxPriority: 第 5 个参数是任务优先级。 —— pvCreatedTask: 第 6个参数是任务句柄,用于区分不同的任务。
返回:任务状态
二 任务删除函数
任务删除使用函数 vTaskDelete():
函数原型:
void vTaskDelete(
TaskHandle_t xTask );
参数描述: 函数 vTaskDelete 用于实现 FreeRTOS 操作系统的任务删除。 第 1 个参数填要删除任务的句柄 使用这个函数要注意以下问题:
- 在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1才有效
#define INCLUDE_vTaskDelete 1 - 如果用往此函数里面填的任务 ID 是 NULL,即数值 0 的话,那么删除的就是当前正在执行的任务,此任务被删除后, FreeRTOS 会切换到任务就绪列表里面下一个要执行的最高优先级任务。
- 在 FreeRTOS 中,创建任务所需的内存需要在空闲任务中释放, 如果用户在 FreeRTOS 中调用了这个函数的话,一定要让空闲任务有执行的机会, 否则这块内存是无法释放的。另外, 创建的这个任务在使用中申请了动态内存,这个内存不会因为此任务被删除而删除,这一点要注意, 一定要在删除前将此内存释放。
三 任务栈的大小
—— 64 字节 对于 Cortex-M3 内核和未使用 FPU(浮点运算单元) 功能的 Cortex-M4 内核在发生中断时需要将 16 个通用寄存器全部入栈, 每个寄存器占用 4 个字节,也就是 16x*4 = 64 字节的空间。可能发生几次中断嵌套就是要 64 乘以几即可。 当然,这种是最坏执行情况,也就是所有的寄存 器都入栈。 ( 注:任务执行的过程中发生中断的话,有 8 个寄存器是自动入栈的,这个栈是任务栈, 进入中断以后其余寄存器入栈以及发生中断嵌套都是用的系统栈)
—— 200 字节 对于具有 FPU(浮点运算单元) 功能的 Cortex-M4 内核, 如果在任务中进行了浮点运算,那么在发生中断的时候除了 16 个通用寄存器需要入栈,还有 34 个浮点寄存器也是要入栈的, 也就是(16+34)*x4 = 200 字节的空间。当然,这种是最坏执行情况,也就是所有的寄存器都入栈。 ( 注:任务执行的过程中发送中断的话,有 8 个通用寄存器和 18 个浮点寄存器是自动入栈的,这个栈是任务栈, 进入中断以后其余通用寄存器和浮点寄存器入栈以及发生中断嵌套都是用的系统栈)
总结: 任务栈的大小就是寄存器全部入栈所占用的字节,每个寄存器占用的字节乘以寄存器数量。
四 任务的状态
—— Running—运行态 当任务处于实际运行状态被称之为运行态, 即 CPU 的使用权被这个任务占用。 —— Ready—就绪态 处于就绪态的任务是指那些能够运行( 没有被阻塞和挂起), 但是当前没有运行的任务, 因为同优先级或更高优先级的任务正在运行。 —— Blocked—阻塞态 由于等待信号量,消息队列,事件标志组等而处于的状态被称之为阻塞态,另外任务调用延迟函数也会处于阻塞态。 —— Suspended—挂起态 类似阻塞态,通过调用函数 vTaskSuspend()对指定任务进行挂起,挂起后这个任务将不被执行,只有调用函数 xTaskResume()才可以将这个任务从挂起态恢复。
五 任务的启动
使用函数: vTaskStartScheduler()
函数原型:
void vTaskStartScheduler( void );
函数描述: 函数 vTaskStartScheduler 用于启动 FreeRTOS 调度器, 即启动 FreeRTOS 的多任务执行。 使用这个函数要注意以下几个问题:
- 空闲任务和可选的定时器任务是在调用这个函数后自动创建的。
- 正常情况下这个函数是不会返回的, 运行到这里极有可能是用于定时器任务或者空闲任务的 heap 空间不足造成创建失败, 此时需要加大 FreeRTOSConfig.h 文件中定义的 heap 大小:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) )
六 任务挂起
使用函数: xTaskSuspend()
函数原型:
void vTaskSuspend(
TaskHandle_t xTaskToSuspend);
函数描述: 函数 vTaskSuspend 用于实现 FreeRTOS 操作系统的任务挂起。 —— 第 1 个参数填要挂起任务的句柄 使用这个函数要注意以下问题:
- 在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1才有效
#define INCLUDE_vTaskSuspend 1
- 如果用往此函数里面填的任务 ID 是 NULL,即数值 0 的话,那么挂起的就是当前正在执行的任务,此任务被挂起后, FreeRTOS 会切换到任务就绪列表里面下一个要执行的高优先级任务。
- 多次调用此函数的话,只需调用一次 vTaskResume 即可将任务从挂起态恢复。
七 任务恢复
使用函数 : xTaskResume()
函数原型:
void vTaskResume(
TaskHandle_t xTaskToResume);
函数描述: —— 第 1 个参数填要恢复任务的句柄 使用这个函数要注意以下问题:
- 在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1才有效
#define INCLUDE_vTaskSuspend 1 - 多次调用函数 vTaskSuspend 的话,只需调用一次 vTaskResume 即可将任务从挂起态恢复。
- 此函数是用于任务代码中调用的,故不可以在中断服务程序中调用此函数,中断服务程序中使用的
xTaskResumeFromISR(), 以后缀 FromISR 结尾。
八 中断方式的任务恢复
使用函数(中断方式) : xTaskResumeFromISR()
函数原型:
void vTaskResumeFromISR(
TaskHandle_t xTaskToResume);
函数描述: 函数 vTaskResumeFromISR 用于实现 FreeRTOS 操作系统的任务恢复。 —— 第 1 个参数填要恢复任务的句柄 使用这个函数要注意以下问题:
1.在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1才有效
#define INCLUDE_xResumeFromISR 1
- 多次调用函数 vTaskSuspend 的话,只需调用一次 vTaskResumeFromISR 即可将任务从挂起态恢复。
- 如果用户打算采用这个函数实现中断与任务的同步,要注意一种情况, 如果此函数的调用优先于函数vTaskSuspend 被调用, 那么此次同步会丢失,这种情况下建议使用信号量来实现同步。
- 此函数是用于中断服务程序中调用的,故不可以在任务中使用此函数,任务中使用的是 vTaskResume。
|