简单聊一下FreeRTOS

FreeRTOS 是一个轻量级的实时操作系统(RTOS),特别适合嵌入式开发,比如用在 ESP32、STM32 这种小芯片上。

啥是 FreeRTOS?

想象你在开饭店,厨房只有一个厨师(单线程),忙不过来咋办?雇几个厨师(多线程),但得有人管着,不然乱套。FreeRTOS 就像个“厨房经理”,帮你调度多个任务(线程),让它们在小小的芯片上高效跑起来,还能保证关键任务优先干。它特别适合需要“实时”响应的场景,比如传感器一有数据就得马上处理。

简单说:FreeRTOS 是一个小而美的任务调度系统,帮你在嵌入式设备上跑多任务。

用 FreeRTOS 开发时,主要得搞懂这几块:任务管理、同步工具、队列通信、时间管理和内存管理

1. 任务管理:让多个活儿一起跑

啥是任务? 任务就是你想让芯片干的活儿,比如点灯、读传感器、发数据。FreeRTOS 能同时跑多个任务,还能决定谁先干。

例子:点灯和读温度

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

void blink_task(void *pvParameters) {
    while (1) {
        printf("灯闪一下\n");
        vTaskDelay(1000 / portTICK_PERIOD_MS); // 等1秒
    }
}

void temp_task(void *pvParameters) {
    while (1) {
        printf("读温度\n");
        vTaskDelay(2000 / portTICK_PERIOD_MS); // 等2秒
    }
}

int main() {
    xTaskCreate(blink_task, "Blink", 2048, NULL, 1, NULL); // 任务1:点灯
    xTaskCreate(temp_task, "Temp", 2048, NULL, 1, NULL);   // 任务2:读温度
    vTaskStartScheduler(); // 开跑
    return 0;
}

xTaskCreate(函数, 名字, 栈大小, 参数, 优先级, 句柄):创建任务。 vTaskDelay(毫秒 / portTICKPERIODMS):让任务睡一会儿,别一直占着 CPU。 输出可能是:

灯闪一下
读温度
(等1秒)
灯闪一下
(等1秒)
灯闪一下
读温度

要掌握啥?

创建任务:xTaskCreate。

任务优先级:数字越大越优先(比如 2 比 1 先跑)。

任务休眠:vTaskDelay 让出 CPU,别卡死。

2. 同步工具:别抢着干活

啥是同步? 多个任务可能抢资源,比如都想写串口。FreeRTOS 提供信号量和互斥锁,管住谁先谁后。

例子:用信号量控制串口

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"

SemaphoreHandle_t serial_lock;

void task1(void *pvParameters) {
    while (1) {
        if (xSemaphoreTake(serial_lock, portMAX_DELAY) == pdTRUE) {
            printf("任务1: 用串口\n");
            vTaskDelay(500 / portTICK_PERIOD_MS);
            xSemaphoreGive(serial_lock); // 释放
        }
    }
}

void task2(void *pvParameters) {
    while (1) {
        if (xSemaphoreTake(serial_lock, portMAX_DELAY) == pdTRUE) {
            printf("任务2: 用串口\n");
            vTaskDelay(500 / portTICK_PERIOD_MS);
            xSemaphoreGive(serial_lock);
        }
    }
}

int main() {
    serial_lock = xSemaphoreCreateMutex(); // 创建互斥锁
    xTaskCreate(task1, "T1", 2048, NULL, 1, NULL);
    xTaskCreate(task2, "T2", 2048, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}

xSemaphoreCreateMutex():创建互斥锁。

xSemaphoreTake(锁, 等待时间):拿锁,没拿到就等。

xSemaphoreGive(锁):还锁。

输出可能是:

任务1: 用串口
(等0.5秒)
任务2: 用串口
(等0.5秒)
任务1: 用串口

要掌握啥? 互斥锁:xSemaphoreCreateMutex、Take、Give,防抢资源。 二进制信号量:xSemaphoreCreateBinary,适合“通知”场景。 等待时间:portMAX_DELAY(一直等)或具体 ticks。

3. 队列通信:任务间传东西

啥是队列? 任务之间得传数据,比如传感器任务把温度传给显示任务。队列就像个“传送带”。

例子:传温度数据

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

QueueHandle_t temp_queue;

void sensor_task(void *pvParameters) {
    int temp = 25;
    while (1) {
        xQueueSend(temp_queue, &temp, portMAX_DELAY); // 发数据
        temp++;
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void display_task(void *pvParameters) {
    int received_temp;
    while (1) {
        if (xQueueReceive(temp_queue, &received_temp, portMAX_DELAY) == pdTRUE) {
            printf("显示温度: %d\n", received_temp);
        }
    }
}

int main() {
    temp_queue = xQueueCreate(5, sizeof(int)); // 队列能存5个int
    xTaskCreate(sensor_task, "Sensor", 2048, NULL, 1, NULL);
    xTaskCreate(display_task, "Display", 2048, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}

xQueueCreate(长度, 数据大小):创建队列。

xQueueSend(队列, 数据指针, 等待时间):发数据。

xQueueReceive(队列, 接收指针, 等待时间):收数据。

输出:

显示温度: 25
(等1秒)
显示温度: 26

要掌握啥?

创建队列:xQueueCreate。

发送和接收:xQueueSend 和 xQueueReceive。

队列满/空处理:用返回值判断。

  1. 时间管理:定时干活 啥是时间管理? 有些活儿得定时跑,比如每秒检查一次状态。FreeRTOS 有软件定时器。

例子:定时打印

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"

void timer_callback(TimerHandle_t xTimer) {
    printf("定时器喊: 到点了!\n");
}

int main() {
    TimerHandle_t timer = xTimerCreate("MyTimer", 1000 / portTICK_PERIOD_MS, pdTRUE, NULL, timer_callback);
    xTimerStart(timer, 0); // 启动定时器
    vTaskStartScheduler();
    return 0;
}

xTimerCreate(名字, 周期, 是否重复, 参数, 回调):创建定时器。 xTimerStart(定时器, 等待时间):开跑。

输出:

定时器喊: 到点了!
(等1秒)
定时器喊: 到点了!

要掌握啥?

创建定时器:xTimerCreate。

启动/停止:xTimerStart、xTimerStop。

单次 vs 重复:pdFALSE(一次)或 pdTRUE(循环)。

5. 内存管理:别乱用空间

啥是内存管理?

嵌入式设备内存小,FreeRTOS 默认用动态内存分配(pvPortMalloc),但得小心用。

例子:任务栈大小

xTaskCreate(my_task, "Task", 2048, NULL, 1, NULL); // 栈2048字节

栈太小(比如 512),任务可能崩溃。 栈太大,浪费内存。

要掌握啥?

栈大小:调 xTaskCreate 的第3个参数,够用就行。

动态分配:pvPortMalloc 和 vPortFree,别漏内存。

配置:了解 FreeRTOSConfig.h 里的 configTOTALHEAPSIZE。

总结:程序员的核心技能 任务管理:会创建任务、调优先级、用 vTaskDelay。 同步工具:用信号量、互斥锁防冲突。 队列通信:任务间传数据靠队列。 时间管理:定时器搞定周期任务。 内存管理:栈和堆别用崩。

文档信息

版权声明:可自由转载(请注明转载出处)-非商用-非衍生

发表时间:2025年7月1日 11:00