前言
ESP-IDF FreeRTOS 是基于 Vanilla FreeRTOS v10.4.3
参考: 乐鑫
配置
原版 FreeRTOS 允许端口和应用程序通过向 添加各种宏来配置内核。通过这些宏,可以启用或禁用内核的调度行为和各种内核功能。但是,在 ESP-IDF FreeRTOS 中,“FreeRTOSConfig.h”文件被视为私有文件,用户不得修改。向用户公开的任何 FreeRTOS 配置都将通过 menuconfig 完成。#define config…FreeRTOSConfig.h
ESP-IDF FreeRTOS 应用
与 Vanilla FreeRTOS 不同,用户不得调用 vTaskStartScheduler() 。相反,ESP-IDF FreeRTOS 会自动启动。入口点是用户定义的函数。void app_main(void)
通常,用户将从 生成其应用程序的其余任务。app_main
允许该函数在任何时候(即,在应用程序终止之前)返回。app_main
从任务调用该函数。app_main main
该任务是 ESP-IDF 在启动时自动生成的多个任务之一。这些任务是:main
任务接口
头文件
Components/FreeRTOS/include/FreeRTOS/task.h
功能
常用函数
创建任务并将其添加到准备运行的任务列表中。
static inline BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, 常量 uint32_t usStackDepth, void *const pvParameters, UBaseType_t uxPriority, TaskHandle_t *const px创建任务)
在内部,在 FreeRTOS 实施中,任务使用两个内存块。第一个块用于保存任务的数据结构。任务使用第二个块作为其堆栈。如果使用 xTaskCreate() 创建任务,则两个内存块都会在 xTaskCreate() 函数中自动动态分配。(见 https://www.FreeRTOS.org/a00111.html)。如果使用 xTaskCreateStatic() 创建任务,则应用程序编写器必须提供所需的内存。因此,xTaskCreateStatic() 允许在不使用任何动态内存分配的情况下创建任务。
请参阅 xTaskCreateStatic() 了解不使用任何动态内存分配的版本。
xTaskCreate() 只能用于创建对整个微控制器内存映射具有不受限制访问权限的任务。包含 MPU 支持的系统也可以使用 xTaskCreateRestricted() 创建 MPU 约束任务。
参数
pvTaskCode – 指向任务输入函数的指针。必须实现任务以永不返回(即连续循环),或者应使用 vTaskDelete 函数终止任务。
pcName – 任务的描述性名称。这主要用于方便调试。configMAX_TASK_NAME_LEN定义的最大长度 - 默认值为 16。
usStackDepth – 指定为字节数的任务堆栈的大小。请注意,这与原版 FreeRTOS 不同。
pvParameters – 将用作正在创建的任务的参数的指针。
uxPriority – 任务应运行的优先级。包含 MPU 支持的系统可以选择通过设置优先级参数的位portPRIVILEGE_BIT在特权(系统)模式下创建任务。例如,要创建优先级为 2 的特权任务,uxPriority 参数应设置为 ( 2 | portPRIVILEGE_BIT )。
pxCreatedTask – 用于传回可以引用创建的任务的句柄。
返回值
pdPASS(如果任务已成功创建并添加到就绪列表中),否则在文件 projdefs.h 中定义错误代码
用法示例:
// Task to be created.
void vTaskCode( void * pvParameters )
{
for( ;; )
{
// Task code goes here.
}
}
// Function that creates a task.
void vOtherFunction( void )
{
static uint8_t ucParameterToPass;
TaskHandle_t xHandle = NULL;
// Create the task, storing the handle. Note that the passed parameter ucParameterToPass
// must exist for the lifetime of the task, so in this case is declared static. If it was just an
// an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
// the new task attempts to access it.
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
configASSERT( xHandle );
// Use the handle to delete the task.
if( xHandle != NULL )
{
vTaskDelete( xHandle );
}
}
注意
如果程序使用线程局部变量(用“__thread”关键字指定的变量),那么它们的存储空间将在任务的堆栈上分配。
延时函数
void vTaskDelay(const TickType_t xTicksToDelay)
延迟给定数量的即时报价的任务。任务保持阻塞状态的实际时间取决于刻度率。常数portTICK_PERIOD_MS可用于根据即时报价率实时计算 - 具有一个即时报价周期的分辨率。
INCLUDE_vTaskDelay必须定义为 1 才能使用此函数。有关详细信息,请参阅配置部分。
vTaskDelay() 指定任务希望取消阻止的时间相对于调用 vTaskDelay() 的时间。例如,指定 100 个时钟周期将导致任务在调用 vTaskDelay() 后取消阻止 100 个时钟周期。因此,vTaskDelay() 不能提供控制周期性任务频率的好方法,因为通过代码以及其他任务和中断活动的路径将影响调用 vTaskDelay() 的频率,从而影响任务下一次执行的时间。请参阅 xTaskDelayUntil() 了解旨在促进固定频率执行的替代 API 函数。它通过指定调用任务应取消阻止的绝对时间(而不是相对时间)来实现此目的。
示例
void vTaskFunction( void * pvParameters )
{
// Block for 500ms.
const TickType_t xDelay = 500 / portTICK_PERIOD_MS;
for( ;; )
{
// Simply toggle the LED every 500ms, blocking between each toggle.
vToggleLED();
vTaskDelay( xDelay );
}
}
更多 blog bkstudy top