04 - 核心编程
FreeRTOS 任务管理与内存管理
FreeRTOS 基础
ESP32 使用 FreeRTOS 作为实时操作系统,支持双核并行执行。
核心概念
┌────────────────────────────────────────┐
│ CPU Core 0 │
│ ┌──────────┐ ┌──────────┐ │
│ │ Task A │ │ Task B │ │
│ │ (High) │ │ (Medium) │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ ┌────▼──────────────▼─────┐ │
│ │ Task Scheduler │ │
│ └──────────────────────────┘ │
└────────────────────────────────────────┘
任务状态
┌─────────┐
│ Ready │
└────┬────┘
│ 调度
┌────────┼────────┐
│ │ │
┌───▼───┐ ┌──▼──┐ ┌──▼────┐
│Running│ │ Blocked │ │Suspended│
└───────┘ └──────┘ └────────┘
│ │ │
└────────┴────────┘
时间片/事件
任务管理
创建任务
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void task_function(void *parameter)
{
while (1) {
printf("Task running...\n");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void app_main(void)
{
xTaskCreate(
task_function, // 任务函数
"TaskName", // 任务名称
4096, // 栈深度(字)
NULL, // 参数
1, // 优先级
NULL // 任务句柄
);
}任务参数说明
| 参数 | 说明 | 建议值 |
|---|---|---|
| pvTaskCode | 任务函数 | - |
| pcName | 任务名称 | 字符串 |
| usStackDepth | 栈深度(字节=字×4) | 2048-4096 |
| pvParameters | 传入参数 | NULL 或指针 |
| uxPriority | 优先级 (0最低) | 1-10 |
| pxCreatedTask | 任务句柄 | NULL |
删除任务
// 任务内自删
void self_delete_task(void *pvParameters)
{
// 执行任务工作
vTaskDelete(NULL); // 删除自己
}
// 从其他任务删除
void another_task(void)
{
xTaskHandle handle;
xTaskCreate(..., &handle);
vTaskDelete(handle);
}任务间通信
队列 (Queue)
#include "freertos/queue.h"
QueueHandle_t msg_queue;
// 创建队列
msg_queue = xQueueCreate(10, sizeof(int));
// 发送
void sender_task(void *pvParameters)
{
int value = 100;
xQueueSend(msg_queue, &value, portMAX_DELAY);
}
// 接收
void receiver_task(void *pvParameters)
{
int value;
while (1) {
if (xQueueReceive(msg_queue, &value, pdMS_TO_TICKS(1000)) == pdTRUE) {
printf("Received: %d\n", value);
}
}
}信号量 (Semaphore)
#include "freertos/semphr.h"
// 二值信号量
SemaphoreHandle_t binary_sem = xSemaphoreCreateBinary();
// 互斥信号量
SemaphoreHandle_t mutex_sem = xSemaphoreCreateMutex();
// 获取
xSemaphoreTake(mutex_sem, portMAX_DELAY);
// 释放
xSemaphoreGive(mutex_sem);事件组 (Event Group)
#include "freertos/event_groups.h"
#define WIFI_CONNECTED_BIT (1 << 0)
#define MQTT_CONNECTED_BIT (1 << 1)
EventGroupHandle_t event_group = xEventGroupCreate();
// 设置事件
xEventGroupSetBits(event_group, WIFI_CONNECTED_BIT);
// 等待事件
EventBits_t bits = xEventGroupWaitBits(
event_group,
WIFI_CONNECTED_BIT | MQTT_CONNECTED_BIT,
pdTRUE, // 清除已设置位
pdTRUE, // 等待所有位
portMAX_DELAY
);定时器
软件定时器
#include "freertos/timers.h"
TimerHandle_t timer_handle;
void timer_callback(TimerHandle_t xTimer)
{
printf("Timer triggered!\n");
}
void app_main(void)
{
timer_handle = xTimerCreate(
"MyTimer", // 名称
pdMS_TO_TICKS(1000), // 周期 1秒
pdTRUE, // 自动重载
(void *)0, // 定时器ID
timer_callback // 回调
);
xTimerStart(timer_handle, 0);
}内存管理
堆内存
#include "esp_heap_caps.h"
// 通用内存分配
void *ptr = malloc(1024);
free(ptr);
// 带特定属性分配 (DRAM)
void *ptr = heap_caps_malloc(1024, MALLOC_CAP_8BIT);
// 带特定属性分配 (DMA)
void *ptr = heap_caps_malloc(1024, MALLOC_CAP_DMA);
// 获取可用内存
size_t free_heap = esp_get_free_heap_size();
size_t min_free = esp_get_minimum_free_heap_size();静态分配
// 静态任务内存
static StaticTask_t task_buffer;
static StackType_t task_stack[4096];
void app_main(void)
{
xTaskCreateStatic(
task_function,
"StaticTask",
4096,
NULL,
1,
task_stack,
&task_buffer
);
}双核执行
核心绑定
// 在 Core 0 上运行
xTaskCreatePinnedToCore(
task_function,
"TaskCore0",
4096,
NULL,
1,
NULL,
0 // Core 0
);
// 在 Core 1 上运行
xTaskCreatePinnedToCore(
task_function,
"TaskCore1",
4096,
NULL,
1,
NULL,
1 // Core 1
);任务亲和性
┌─────────────────┬─────────────────┐
│ Core 0 │ Core 1 │
├─────────────────┼─────────────────┤
│ WiFi 处理任务 │ 传感器采集任务 │
│ 网络协议栈 │ 数据处理任务 │
│ 系统任务 │ 用户交互任务 │
└─────────────────┴─────────────────┘
临界区
// 方法1: 禁用中断
taskENTER_CRITICAL();
// 临界代码
taskEXIT_CRITICAL();
// 方法2: 任务临界区 (带端口)
taskENTER_CRITICAL(&mux);
...
taskEXIT_CRITICAL(&mux);
// 方法3: 锁调度器
vTaskSuspendAll();
// 临界代码
xTaskResumeAll();参考资料
官方文档
- FreeRTOS 官方文档 - FreeRTOS 实时操作系统完整文档
- ESP-IDF FreeRTOS 文档 - ESP-IDF 中的 FreeRTOS 实现
- ESP-IDF 任务管理 API - xTaskCreate、vTaskDelete 等 API 详解
- ESP-IDF 队列 API - 任务间通信队列使用
- ESP-IDF 事件组 API - 事件组同步机制
核心调度
- ESP32 双核调度 - 对称多核处理 (SMP) 详解
- FreeRTOS 任务优先级 - 优先级配置与调度策略
- FreeRTOS 内存管理 - 堆内存分配策略
图片参考

相关链接
反向链接
- 03_开发环境 - ESP-IDF、Arduino、PlatformIO 配置
- 05_GPIO_外设 - 通用输入输出、LEDC、PWM
- 06_通信协议 - I2C、SPI、UART
- README - 学习笔记索引首页
进阶学习
- 05_GPIO_外设 - 实践GPIO控制
- 06_通信协议 - 掌握外设通信
下一步
- 学习 05_GPIO_外设 实践GPIO控制
- 学习 06_通信协议 掌握外设通信