尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
FreeRTOS 学习文档
FreeRTOS 使用原因在代码量大、多任务要求实时进行时使用一个 while 循环进行逻辑开发就会很不方便如图裸机状态下追求任务同时完成。如果使用 FreeRTOS 只需要显而易见变简单了。理论学习部分OsKernelStart()函数运行后程序进入 FreeRTOS。任务Task任务调度的实现控制 PC 寄存器指向不同的任务。FreeRTOS 运行任务会给任务分配时间片。任务运行状态就绪态、运行态、阻塞态、挂起态任务刚生成是就绪态 → 分配时间片后任务开始运行进入运行态 → 时间片时间到时回到就绪态给其他就绪态任务分配时间片。当任务运行osDelay之类函数时任务进入阻塞态之后时间片分配给其他就绪态任务。挂起态类似。使用osDelay的原因就是它能让任务进入阻塞态让出时间片。任务优先级高优先级任务一直处于运行态时低优先级任务无法运行队列 Queue任务间需要数据交流时将数据塞入队列可以多对一、一对多队列任务被塞满队列有长度队列被塞满后的情况取决于设置的阻塞超时时间参数xTicksToWait。超时时间为 0 时函数会返回失败标志errQUEUE_FULL新数据会被直接丢弃队列中的现有数据不受任何影响。超时时间设为有限值xTicksToWait 0当前任务会被挂起Blocked 状态让出 CPU 给其他任务使用。在超时时间内如果有其他任务从该队列中读取并取走了一个数据腾出了空间当前任务会立刻被唤醒把新数据写入队列并返回pdPASS成功。如果超时时间到了队列依然是满的任务会被自动唤醒函数返回errQUEUE_FULL新数据抛弃写入失败。超时时间设为永久等待xTicksToWait portMAX_DELAY任务挂起态直到队列有空位。只有当其他任务从队列中取走数据腾出空间时该任务才会被唤醒并将数据写入。如果在 FreeRTOS 配置中启用了INCLUDE_vTaskSuspend它将无限期等待进入阻塞态永远不会因为超时而返回errQUEUE_FULL。基于队列实现的二进制信号量Binary Semaphores长度只有 1 的队列只有一位0/1 可以当成任务的开关。计数信号量Counting Semaphores长度任意。盘点事件记录事件发生了多少次。资源管理初始化时计数信号量初始化为某资源的数量有任务使用此资源时使用osSemaphoreAcquire()获取信号量信号量减一。资源使用完后可通过osSemaphoreRelease()释放信号量。信号量归零时任务无法获取此资源进入阻塞态。互斥锁Mutex用途互斥锁Mutex是 FreeRTOS 中用于保护共享资源的同步机制。它保证同一时刻只有一个任务访问某个资源避免多个任务同时操作导致数据冲突。常用于保护串口、CAN 总线、共享变量等资源确保系统运行稳定可靠。接下来进入 CubeMX 各部分配置和原理FreeRTOS 看着东西多其实大部分需要的都默认配置好了。开始Config parameters这里边的东西看着多其实绝大多数都不用管用默认的就行了下面列出一些可能需要自己配的东西。MPU/FPUENABLE_FPU浮点运算单元何时开启代码中有大量float/double浮点数计算如 PID 控制、DSP 数字信号处理、复杂滤波算法等且芯片硬件本身支持 FPU。何时关闭主要做逻辑控制、串口通信、GPIO 操作等没有密集浮点运算时。开启它会稍微增加任务切换时的堆栈Context Switch开销。Memory management settings这个需要配置一下TOTAL_HEAP_SIZE具体配置方法如下堆大小TOTAL_HEAP_SIZE怎么算看你要创建多少个任务每个任务的栈大小加起来再加上队列、信号量的内存一般 1KB乘以 1.5 倍留余量栈溢出检测选择 2非必须。User Constants这个相当于 CubeMX 的#define在User Constants中填入名称如STACK_LARGE与数值如1024之后生成代码后你的main.h文件里边会出现#define定义的你写的User Constants。4️⃣ User Constants用户常量— 定义常量便于管理打开User Constants标签在这里定义任务栈大小和优先级常量。为什么要定义常量改参数时只需改一个地方不用改代码。这个就是在手动创建任务时有用总体来说感觉比较鸡肋。Tasks and Queues任务和队列— 创建任务这应该是最重要的一个了。创建任务1. 任务句柄与结构体属性映射填入的参数界面上的Task Name、Priority、Stack Size等会被打包成一个叫osThreadAttr_t的结构体同时生成一个任务句柄C/* 1. 生成的任务句柄控制块指针 */ osThreadId_t myTask03Handle; /* 2. 映射弹窗里配置的所有属性 */ const osThreadAttr_t myTask03_attributes { .name myTask03, // -- 对应 Task Name .stack_size 128 * 4, // -- 对应 Stack Size (128 Words * 4 512 Bytes) .priority (osPriority_t) osPriorityLow, // -- 对应 Priority };2. 任务创建与启动代码在初始化函数中在MX_FREERTOS_Init()函数中系统会调用创建函数将任务拉起Cvoid MX_FREERTOS_Init(void) { /* ... 其他初始化 ... */ /* 映射 Parameter 和 动态/静态分配(Allocation) */ myTask03Handle osThreadNew( StartTask03, // -- 对应 Entry Function (入口函数) NULL, // -- 对应 Parameter (传递的参数) myTask03_attributes // -- 传入上面配置的属性 ); /* ... */ }3. 任务的执行函数实体代码末尾CubeMX 会在文件末尾自动为你生成这个任务的具体死循环函数模板C/* 对应 Entry Function 填写的函数名 */ void StartTask03(void *argument) { /* USER CODE BEGIN StartTask03 */ /* 函数的主循环你的代码写在这里 */ for(;;) { osDelay(1); // 避免死循环独占 CPU } /* USER CODE END StartTask03 */ }创建队列1. 队列句柄与属性声明C/* 1. 生成的队列句柄指针 */ osMessageQueueId_t myQueue01Handle; /* 2. 映射弹窗里的队列属性 */ const osMessageQueueAttr_t myQueue01_attributes { .name myQueue01 // -- 对应 Queue Name };2. 队列的创建在MX_FREERTOS_Init初始化函数中Cvoid MX_FREERTOS_Init(void) { /* ... */ /* 映射 Queue Size (16) 和 Item Size (uint16_t) */ myQueue01Handle osMessageQueueNew( 16, // -- 对应 Queue Size (队列深度) sizeof(uint16_t), // -- 对应 Item Size (单数据占用字节数) myQueue01_attributes // -- 传入上面定义的属性 ); /* ... */ }队列在代码里是怎么传数据的解释队列通过“内存数据拷贝”保存发送方数据当接收方读取空队列时自动阻塞有新数据进入时立刻唤醒执行。实际代码演示C/* 假设传一个遥控器摇杆结构体 */ typedef struct { int16_t vx; int16_t vy; } RC_Cmd_t; /* 任务 A发送方通信/接收任务 */ void CommsTask(void *argument) { RC_Cmd_t send_cmd {100, -50}; // 准备数据 // 将数据写入队列超时设为0满了直接跳过 osMessageQueuePut(myQueue01Handle, send_cmd, 0, 0); } /* 任务 B接收方底盘控制任务 */ void ChassisTask(void *argument) { RC_Cmd_t recv_cmd; // 从队列读数据若队列为空则阻塞死等osWaitForever不占 CPU if (osMessageQueueGet(myQ
RELATED

相关推荐

基于SpringBoot+Vue的享瘦减肥服务系统设计与实现

基于SpringBoot+Vue的享瘦减肥服务系统设计与实现

选题背景 随着现代社会生活节奏的加快和饮食结构的改变,肥胖问题日益成为全球性健康挑战。世界卫生组织(WHO)数据显示,全球肥胖人口在过去40年里增长了近三倍,肥胖及相关代谢性疾病(如糖尿病、心血管疾病&a…

📅 2026/9/24 2:23:45
嵌入式开发板全解析:从核心原理到实战选型指南

嵌入式开发板全解析:从核心原理到实战选型指南

1. 项目概述:从“黑盒子”到“万能积木”干了十几年硬件开发,从画第一块51单片机板子,到后来玩转各种ARM、FPGA,我越来越觉得,对“开发板”的理解深度,直接决定了一个硬件工程师的成长速度和天花板。很多刚…

📅 2026/8/22 16:57:16
ST、NXP、英飞凌MCU选型实战指南:从架构解析到开发环境搭建

ST、NXP、英飞凌MCU选型实战指南:从架构解析到开发环境搭建

1. 项目概述:为什么需要一份MCU“选型地图”?在嵌入式开发的江湖里混迹了十几年,我经手过的项目从消费电子到工业控制,从简单的玩具到复杂的汽车电子,几乎都绕不开MCU(微控制器)这颗“心脏”。而…

📅 2026/8/22 16:57:17
MORE NEWS

更多资讯

📰

OpenClaw 在Centos7上快速部署与简单验证

OpenClaw 在Centos7上快速部署与简单验证 Install # 添加NodeSource仓库 curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash - # 安装Node.js sudo yum install -y nodejs # 验证安装 node --version npm --version# 安装OpenClaw curl -fsSL https://openclaw.ai…

📰

DeepSeek - 尝试一下以Responses API方式去使用DeepSeek模型

1. 简单介绍 当前AI大模型以及Agent技术迅速普及和推广,DeepSeek公司也在这波大潮流中得到很大的发展,下面是forbes的数据, 之前在查看DeepSeek技术资料的时候,deepseek-flash和deepseek-v4-pro不是都支持Response API的&#xf…

📰

ESP32脑电波控制家电:NPG Lite与红外模块实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Linux系统调试课(CPU篇)CPU亲和性与多进程调度

文章目录 一、概述 二、为什么需要 CPU 亲和性 2.1 跨核迁移的代价 2.2 亲和性分类 2.3 负载均衡与亲和性的关系 三、基本概念 3.1 cpumask 与亲和性掩码 3.2 中断亲和性原理 四、源码解析:__set_cpus_allowed_ptr 4.1 函数原型 4.2 SDK 真实实现 4.3 执行流程图 五、RK3506 设…

📰

Razzle 接入 LESS:razzle-plugin-less 插件安装、配置项与 loader 处理链路全解析

前端构建工具前端构建后端 【免费下载链接】razzle ✨ Create server-rendered universal JavaScript applications with no configuration 项目地址: https://gitcode.com/gh_mirrors/ra/razzle 点击查看 免费下载 本指南围绕 Razzle 官方插件 razzle-plugin-less…

📰

深度 | 云栖大会阿里亮底牌:模型芯片云三箭齐发,正式站上追ASI的跑道

2026 云栖大会,阿里把「AI 模型、AI 芯片、AI 云」三个词摆到战略 C 位。吴泳铭说未来机器思考总量达人类 1000 倍,平头哥亮出 3 倍算力的真武 V900,Qwen 公开了迈向 ASI 的路线图。 我判断,这届云栖的分量不在单个产品&#xff0…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬