news 2026/4/15 17:06:01

从FreeRTOS的Task API出发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从FreeRTOS的Task API出发

从FreeRTOS的Task API出发

前言

笔者注意到,不少教程是真的直接上来就告诉你FreeRTOS的架构是如何的,库库的告诉你要理解什么是 RTOS、FreeRTOS 在嵌入式的作用与应用场景;环境准备。但是实际上,如果我们只是先把宏观的知识塞到期盼学习FreeRTOS的嵌入式人,恐怕只会学的有些难受(尽管后面显然会意识到FreeRTOS到底适合在哪些场景)

所以这篇博客压根不打算跟你起手扯大的,而是带你先体验一圈RTOS的编程范式(或者更加通俗的说——如果你使用RTOS组织你的工程,你的代码看起来像是什么样子的)。这里,我们就能带出来基本的任务相关的API(注意笔者不计划在这片博客疯狂讲RTOS的原理,不在这里讲)

从前后台程序到 RTOS 任务模型

笔者认为,在真正学习 Task API 之前,先建立正确的编程范式认知非常重要。

在最传统的无RTOS的单片机上,也就是在绝大多数 8 位 / 32 位单片机裸机工程中,程序结构通常是:

intmain(void){init();// <- 一部分硬件初始化的工作while(1){TaskA();TaskB();TaskC();}}

同时辅以若干中断:

voidSysTick_Handler(void){tick++;}

这种大家最开始学习单片机程序的时候,编写的程序就是满足这样的前后台程序架构的,你可以看到,后台就在默默的轮询执行任务,前台则是招待板上硬件的中断,打断我们的执行处理相关的业务代码,当然,中断内一般咱们不会去执行长期的阻塞任务防止单片机挂死,一般都是直接设置标志位。所以简单的说:

  • 前台(Foreground):中断服务程序 ISR
  • 后台(Background)main()中的while(1)轮询逻辑

这种前后台程序架构比较直接,我相信大部分嵌入式工程师,对于身兼数职(又是画板子又是写程序又是测试又是拉客户的)的同志,这种结构简单,极易上手,代码出问题了有时候一下子执行逻辑是如何触发这个错误的时序图就蹦出来了(也就是代码可控、可预测),最重要的是——有时候使用的单片机就没法跑啥东西的时候,其实只能这样编写了。

但是慢慢伴随业务的扩大,如何协调这些具体的业务代码本身就构成了一个令人头疼的难题了。举个例子,我们假设真的有突发很重要的任务需要执行(比如说用户触发了按钮需要在漫长的后台轮询任务中打断执行流),但是在没有RTOS的项目中这个事情就比较难搞了——毕竟这种轮询都是我让你 → 你让他 → 他再让回来,如果我们每个函数都“没有分寸感”(这里说的分寸感是指——你不得不让一些函数要有速度执行的下限,也就是不能太慢;或者是必须异步;或者是必须时时刻刻的判断其他任务是否触发的变量),系统就直接整体失效了(比如说用户按了半天按钮才轮循到检查Flag变量的部分,这个体验有时候会很致命)

这种根源就是执行的任务代码是不可以被打断的,或者说,在处理器看来,您给定的所有代码的“重要性”是一样的。这种重要性就是我们后面要谈到的——任务优先级了。

在过去的范式里,我们的代码必须仔细可控的标称函数的行为,不可以过多的越过一些条件(不可以太慢,不可以同步阻塞,随时都可以返回),但是如果我们的业务迭代有些迅速,那么在这样小心翼翼的写代码只会让自己埋没在代码的修改中(改了这个挂了那个)。对于这种复杂的业务场景(这就是笔者不赞同点个灯也要RTOS,除非是教学需求),上RTOS就是合适的。

RTOS 的 Task 编程范式

FreeRTOS引入的核心变化是从“我主动让出 CPU” → “由内核决定谁运行”,意味着我们的代码稍微有了一点点不确定性。但是换来的就是巨大的代码清晰和可维护性,以及最重要的,我们的任务终于有了主次而不是在前后台中成为扁平的一条长链。

在RTOS 中,每一个Task就是我们熟悉的独立执行流,是的,就像你单独为点灯写了一个Main函数,单独为驱动OLED写了一个Main函数一样,现在我们放到一个Task函数放心的while(1)而不用担心程序走不出去了。在这里,调度不是由被执行的代码决定而是由内核调度器决定

很快我们就要写这样的代码了:

voidTaskA(void*param){while(1){DoSomethingA();vTaskDelay(pdMS_TO_TICKS(100));}}

💡 这里的while(1)被内核托管的无限循环,而不是裸奔循环。所以放心大胆的使用


两种模型的本质对比

说了很多,看看这个表格吧:

维度前后台程序FreeRTOS Task
并发模型顺序轮询抢占式调度
延时方式软件计数 / 阻塞内核阻塞
时序管理人工维护内核维护
任务重要性隐式显式(优先级)
可扩展性
可读性依赖经验贴近业务

GPT的总结很好——裸机是“人脑调度”,RTOS 是“内核调度”。


快点端上来罢!我等不及了

正常到这里,笔者看到不少的文章和教程就要开始跟你念经——什么是TCB,什么是任务优先级,什么是调度,乱七八糟的东西就来了,但是没有必要。

FreeRTOS在任务创建的时候就写过很长一串注释,这里的注释里的代码,笔者拿过来了:

// 任务函数的标准原型voidvTaskCode(void*pvParameters);// 示例:一个 LED 闪烁任务voidvLedTask(void*pvParameters){// 任务的局部初始化代码// ...vLedInit();// 如果我们打算在任务里初始化// 任务的主体是一个无限循环for(;;){// 1. 执行任务的实际工作// 比如:切换 LED 状态Toggle_LED();// 2. 主动让出 CPU 或进入阻塞状态// 比如:延时 500msvTaskDelay(pdMS_TO_TICKS(500));}// 任务理论上不应该退出 for(;;) 循环。// 如果需要退出,应使用 vTaskDelete(NULL)。}

笔者在之前的教程中就谈到了如何在上位机上模拟RTOS:

#include"FreeRTOS.h"#include"task.h"#include<stdio.h>voidTask1(void*pv){for(;;){printf("Task1 running\n");vTaskDelay(pdMS_TO_TICKS(1000));}}voidTask2(void*args_pv){for(;;){printf("Task2 running\n");vTaskDelay(pdMS_TO_TICKS(3000));}}intmain(void){xTaskCreate(Task1,"t1",configMINIMAL_STACK_SIZE,NULL,1,NULL);xTaskCreate(Task2,"Task2",configMINIMAL_STACK_SIZE,NULL,1,NULL);vTaskStartScheduler();return0;}

不过也没事,如果你的单片机有移植printf,那太好了,直接CV就能用。

笔者之前的RTOS上位机模拟教程和配置教程:

  1. 在上位机上熟悉FreeRTOS API-CSDN博客
  2. 基于STM32F407ZGT6的硬件平台,(可选CubeMX) + PlatformIO软件开发的FreeRTOS部署指南_platformio freertos-CSDN博客
  3. (1 封私信) 在上位机上熟悉FreeRTOS API——环境配置 - 知乎
  4. (1 封私信) 基于STM32F407ZGT6的硬件平台,(可选CubeMX) + PlatformIO软件开发的FreeRTOS部署指南 - 知乎
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/8 6:39:27

vue基于springboot的基于学生行为的在线教育 学习选课成绩分析系统可视化统计图没有

目录已开发项目效果实现截图开发技术介绍系统开发工具&#xff1a;核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/4/1 9:21:32

vue基于springboot的家庭光伏发电系统能源采集管理系统

目录已开发项目效果实现截图开发技术介绍系统开发工具&#xff1a;核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/4/12 18:11:41

EmotiVoice语音合成在博物馆导览系统中的智能化升级

EmotiVoice语音合成在博物馆导览系统中的智能化升级 在一座安静的博物馆展厅里&#xff0c;游客驻足于一件千年古剑前。耳边响起的不再是千篇一律的机械播报&#xff0c;而是一位声音低沉、语气庄重的老学者娓娓道来&#xff1a;“这柄青铜剑出土于战国墓葬&#xff0c;寒光未褪…

作者头像 李华
网站建设 2026/4/13 19:48:21

可能是你极易忽略的Nginx知识点

点击上方 程序员成长指北&#xff0c;关注公众号回复1&#xff0c;加入高级Node交流群下面是我在nginx使用过程中发现的几个问题&#xff0c;分享出来大家一起熟悉一下nginx问题一先看下面的几个配置# 配置一 location /test {proxy_pass http://192.186.0.1:8080; }# 配置二 l…

作者头像 李华
网站建设 2026/4/15 6:38:16

答辩PPT不再头疼:百考通AI智能结构优化与内容提炼指南

“我的论文有六十页&#xff0c;答辩PPT到底该放什么、不放什么&#xff1f;”这是很多毕业生在制作答辩PPT时的真实困惑。内容取舍困难、逻辑主线模糊&#xff0c;成为答辩准备中的“隐形门槛”。今天我们就来深入聊聊&#xff0c;如何借助百考通AI的智能功能&#xff0c;科学…

作者头像 李华
网站建设 2026/4/13 11:00:46

【Rust日报】 LWN《Rust 内核实验的情况》

LWN《Rust 内核实验的情况》文章报道了在 2025 年 Linux 内核维护者峰会&#xff08;Linux Kernel Maintainers Summit&#xff09; 上的一场关于 Rust 语言在内核中地位的关键讨论。1. 核心结论&#xff1a;实验宣告成功背景&#xff1a; 当 Rust 最初被引入 Linux 内核&#…

作者头像 李华