Skip to content

第 8 章:FreeRTOS 多任务架构

8.1 知识要点

  • FreeRTOS 任务创建、优先级与栈大小配置
  • ESP32-S3 双核绑定(xTaskCreatePinnedToCore
  • 任务间通信:Queue(队列)和 Mutex(互斥锁)
  • 实时任务与通信任务的核心分离架构

8.2 课程内容

ESP32-S3 搭载双核 Xtensa LX7 处理器(Core 0 和 Core 1),FreeRTOS 支持对称多处理(SMP)。合理的任务架构是机器人控制系统实时性的基础:将传感器采样和控制计算绑定到 Core 1(实时核),将通信和日志绑定到 Core 0(通信核),避免相互干扰。

8.3 基础学习

任务优先级规划

FreeRTOS 优先级数值越大越高,configMAX_PRIORITIES 默认为 25。OSRCORE 的三任务架构:

任务核心优先级周期职责
task_sensorCore 15100 ms传感器采样
task_controlCore 1420 ms控制计算
task_commCore 031000 ms状态上报

Queue 与 Mutex

  • Queue:用于任务间传递数据(生产者-消费者模式)。xQueueOverwrite() 适合只需要最新值的场景(如传感器数据)。
  • Mutex:用于保护共享数据结构,防止并发访问导致数据撕裂。

双核绑定

c
// 绑定到 Core 1(实时任务)
xTaskCreatePinnedToCore(task_sensor, "sensor", 4096, NULL, 5, NULL, 1);
// 绑定到 Core 0(通信任务)
xTaskCreatePinnedToCore(task_comm, "comm", 4096, NULL, 3, NULL, 0);

不绑定核心时使用 xTaskCreate(),FreeRTOS 自动调度。

8.4 程序学习

共享状态与同步原语:

c
typedef struct {
    float sensor_val;
    float control_out;
    uint32_t tick;
} shared_state_t;

static shared_state_t g_state;
static SemaphoreHandle_t g_mutex;
static QueueHandle_t g_sensor_q;  // 深度为 1 的队列

// 初始化
g_mutex    = xSemaphoreCreateMutex();
g_sensor_q = xQueueCreate(1, sizeof(sensor_msg_t));

传感器任务(写队列 + 更新共享状态):

c
static void task_sensor(void *arg)
{
    sensor_msg_t msg;
    while (1) {
        msg.value        = read_sensor();
        msg.timestamp_us = esp_timer_get_time();
        xQueueOverwrite(g_sensor_q, &msg);  // 覆盖旧值

        xSemaphoreTake(g_mutex, portMAX_DELAY);
        g_state.sensor_val = msg.value;
        g_state.tick++;
        xSemaphoreGive(g_mutex);

        vTaskDelay(pdMS_TO_TICKS(100));
    }
}

控制任务(读队列,执行 PI 控制):

c
static void task_control(void *arg)
{
    sensor_msg_t msg;
    float integral = 0.0f;
    const float kp = 2.0f, ki = 0.1f, target = 1.25f;

    while (1) {
        if (xQueuePeek(g_sensor_q, &msg, 0) == pdTRUE) {
            float err = target - msg.value;
            integral += err * 0.02f;
            float out = kp * err + ki * integral;

            xSemaphoreTake(g_mutex, portMAX_DELAY);
            g_state.control_out = out;
            xSemaphoreGive(g_mutex);
        }
        vTaskDelay(pdMS_TO_TICKS(20));
    }
}

8.5 课程总结

本章建立了 OSRCORE 的三任务双核架构,掌握了 Queue 和 Mutex 的使用模式。这一架构是后续 PID 闭环控制和完整示例的基础框架,实时任务与通信任务的核心分离保证了控制周期的确定性。


Built for OSRCORE robot development board.