FreeRTOS入门(01):基础说明与使用演示
文章目录
- 目的
- 基础说明
- 系统移植
- 基础使用演示
- 数据类型和命名风格
- 总结
- 碎碎念
目的
FreeRTOS是一个现在非常流行的实时操作系统(Real Time Operating System)。本文将介绍FreeRTOS入门使用相关内容,这篇是第一篇,主要介绍基础背景方面的内容。
FreeRTOS官网:https://www.freertos.org/ (网站现在已更新中文)

Real-time operating system for microcontrollers
Developed in partnership with the world’s leading chip companies over an 18-year period, and now downloaded every 170 seconds, FreeRTOS is a market-leading real-time operating system (RTOS) for microcontrollers and small microprocessors. Distributed freely under the MIT open source license, FreeRTOS includes a kernel and a growing set of IoT libraries suitable for use across all industry sectors. FreeRTOS is built with an emphasis on reliability and ease of use.
微控制器实时操作系统
FreeRTOS 是市场领先的面向微控制器和小型微处理器的实时操作系统 (RTOS),与世界领先的芯片公司合作开发,现在每 170 秒下载一次。FreeRTOS 通过 MIT 开源许可免费分发,包括一个内核和一组不断丰富的 IoT 库,适用于所有行业领域。FreeRTOS 的构建强调可靠性和易用性。
基础说明
OS最核心的功能是调度器,用于调度系统CPU和内存等资源。在大型项目或者多人开发的项目中这通常是必不可少的,没有调度器对资源合理的管理和分配,开发过程中就需要人为花大量时间精力来协调分配资源。
调度器表现到用户而言就是在编写程序时可以编写为一个个独立的任务(task),你可以专心编写每个任务而不太用担心该任务会不会影响其它任务,这是主要是调度器来操心的。
OS其它的功能主要是围绕 task 展开的,用于处理不同 task 间通讯、协同操作等需求。另外OS通常还会提供一些趁手的附加功能。
RTOS在一般的OS基础上针对控制领域特点会更加注重实时响应性能。
系统移植
目前大多数热门的单片机厂家都有给出移植好FreeRTOS的项目示例,很多时候并不需要自己从头进行移植,本文也直接使用现成的模板展开。但是理解FreeRTOS源码结构和移植相关内容对于FreeRTOS后续的使用上会有一定的帮助,所以这里也稍微对相关内容进行介绍。
在FreeRTOS官网下载源码,下图中上面那个包中有非常多热门单片机的移植使用工程示例,如果要自己移植的话可以参考这些示例:

下面是下载解压后其中的部分目录,最核心的就是内核源码部分了:

当然如果要手动移植的话需要自行处理一些芯片特定代码,可以参考上图中的portable目录下内容。系统移植时通常涉及系统定时器、中断、内存这一些内容,其中有部分还需要使用汇编代码来处理,比如任务切换调度过程就必须用到一些汇编代码才能处理。不过大部分情况下参考portable目录下现有的内容来进行其实也不难。
对于FreeRTOS而言在使用时通常还有个 FreeRTOSConfig.h 文件,该文件用于设置FreeRTOS的一些参数选项。这个文件是即使FreeRTOS已经由厂家移植好了,但根据各自的项目需求还可以在这里调整的地方。
本文演示基于沁恒CH32V307单片机官方FreeRTOS项目模板进行,并不需要自己手动移植系统。
沁恒CH32V307单片机基础使用可以参考《沁恒CH32V307单片机入门(01):基础说明与流程体验》:
https://blog.csdn.net/Naisu_kun/article/details/128734532


使用FreeRTOS项目模板新建项目后可以看到项目中已经包含了FreeRTOS的内核代码以及相关配置文件。目前该项目模板工程中 FreeRTOS 内核版本为 V10.4.6。
基础使用演示
使用上面的CH32V307的FreeRTOS项目模板方式创建项目,新项目中只需要替换 main.c 为下面内容:
#include "debug.h"
#include "FreeRTOS.h" // 引入头文件
#include "task.h" // 引入头文件
#include "semphr.h" // 引入头文件SemaphoreHandle_t xMutex; // 声明互斥量,// 下面两个任务中使用了同一个串口,所以需要使用互斥量进行保护/* Task1相关参数与任务处理函数 */
#define TASK1_TASK_PRIO 3
#define TASK1_STK_SIZE 256TaskHandle_t Task1Task_Handler; // 用于保存任务句柄void task1_task(void *pvParameters) // 任务就是函数
{while(1) //每一个任务都是无限循环运行的{xSemaphoreTake(xMutex, portMAX_DELAY); // 申请互斥量,如果别人在使用那么这里就会阻塞直到可用为止printf("USART1_Task1: ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n");xSemaphoreGive(xMutex); // 释放互斥量vTaskDelay(250); // FreeRTOS的延时函数,单位是FreeRTOS的任务周期}
}/* Task2任务处理函数 */
void task2_task(void *pvParameters)
{while(1){xSemaphoreTake(xMutex, portMAX_DELAY);printf("USART1_Task2: 01234567890123456789\r\n");xSemaphoreGive(xMutex);vTaskDelay(500);}
}/* 主函数 */
int main(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);SystemCoreClockUpdate();Delay_Init();USART_Printf_Init(9600); // 使用9600波特率,每秒串口约可通讯960字节,// 默认configTICK_RATE_HZ为500,即每2ms调度一次,每次调度间可以发送约9个字节printf("FreeRTOS Kernel Version:%s\r\n",tskKERNEL_VERSION_NUMBER); // 打印FreeRTOS内核版本号xMutex = xSemaphoreCreateMutex(); // 创建互斥量// 创建一个任务// 创建成功会返回pdPASS(1),失败通常返回errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY(-1),即内存不足xTaskCreate((TaskFunction_t )task1_task, // 任务函数(const char* )"task1", // 任务名称,长度由FreeRTOSConfig.h中configMAX_TASK_NAME_LEN定义(uint16_t )TASK1_STK_SIZE, // 该任务栈深度(栈大小),对于32位架构一个深度为四字节(void* )NULL, // 传递给任务的参数(UBaseType_t )TASK1_TASK_PRIO, // 任务优先级,值越大优先级越高,最大值为FreeRTOSConfig.h中configMAX_PRIORITIES - 1(TaskHandle_t* )&Task1Task_Handler); // 任务句柄,后续可以用过该句柄来操作任务xTaskCreate(task2_task, "task2", 128, NULL, 5, NULL); // 创建一个任务vTaskStartScheduler(); // 任务调度,程序将在这里无序循环while(1){} // 程序不会运行到这里
}
上面代码中创建了两个任务,交替通过USART1打印一些文本,实际效果如下:

FreeRTOS中供用户使用的最核心的功能是Task,除此之外的大部分内容(队列、互斥锁、信号量……)都是为了Task与Task之间交互而服务了。具体的这些相关内容会在后面的文章中详细介绍。
数据类型和命名风格
FreeRTOS对编程风格上有自己的一些规定,但是大多数内容(比如缩进格式、注释格式等)我们并不用太关心,这里只介绍一些FreeRTOS中相对独特的内容。
FreeRTOS的数据类型使用 stdint.h 中定义的一些,但是其中的 char 和 char * 通常包含或者指向 ASCII 字符(也就是默认认为这个必须是有符号类型)。除了这些基本的类型FreeRTOS中还定义了下面四个类型:
TickType_t系统时钟计数类型,32位架构下为32位数据类型;BaseType_t平台架构中最高有效数据类型,32位架构下为32位数据类型;UBaseType_t无符号的BaseType_t;StackType_t供FreeRTOS内部使用;
FreeRTOS中对变量、函数、宏等命名有一定的格式习惯。
变量名:
变量名带有前缀(前缀可以组合)。
| 变量名前缀 | 说明 | 变量名前缀 | 说明 |
|---|---|---|---|
| uc | uint8_t | us | uint16_t |
| ul | uint32_t | x | size_t |
| u | 非stdint类型的无符号类型 | x | 非stdint类型的有符号类型 |
| e | 枚举类型 | p | 指针类型 |
| c | char | pc | char * |
函数名:
对于私有函数使用 prv 作为前缀,对于其它函数使用返回类型和函数所在文件名作为前缀。
| 函数名 | 返回值类型 | 所在文件 |
|---|---|---|
| vTaskDelete | void | task.c |
| xQueueReceive | BaseType_t | queue.c |
| pvTimerGetTimerID | char * | tmer.c |
宏名:
宏名前缀通常和该宏所在文件有关;除前缀外,所有宏均使用大写字母书写,并使用下划线来分隔单词。
| 宏名前缀 | 所在文件 |
|---|---|
| task (如taskENTER_CRITICAL()) | task.h |
| port (如portMAX_DELAY) | portable.h 或 portmacro.h |
| config (比如configUSE_PREEMPTION) | FreeRTOSConfig.h |
| pd (比如pdTRUE) | projdefs.h |
| err (比如errQUEUE_FULL) | projdefs.h |
部分通用宏定义:
| 宏 | 值 | 值 | |
|---|---|---|---|
| pdFALSE | 0 | pdTRUE | 1 |
| pdFAIL | 0 | pdPASS | 1 |
总结
这篇文章对FreeRTOS入门使用相关的一些基础背景内容进行了介绍,还进行了演示使用,更多详细的内容将在接下来的文章中展开。
碎碎念
我刚开始学单片机的时候RTOS比较流行的是μC/OS,FreeRTOS当时还不是很常见,因为其免费特性被很多单片机厂商用于默认的RTOS例程,慢慢的变得常见了。比如现在很流行的ESP32整个开发包默认就是建立在FreeRTOS之上的。
自从FreeRTOS被亚马逊收购后现在发展的也越来越好了。我这篇文章刚开始写的官网还是英文的,现在都更新中文了(虽然感觉是机翻的)。
相关文章:
FreeRTOS入门(01):基础说明与使用演示
文章目录目的基础说明系统移植基础使用演示数据类型和命名风格总结碎碎念目的 FreeRTOS是一个现在非常流行的实时操作系统(Real Time Operating System)。本文将介绍FreeRTOS入门使用相关内容,这篇是第一篇,主要介绍基础背景方面…...
华为OD机试真题Python实现【交换字符】真题+解题思路+代码(20222023)
交换字符 题目 给定一个字符串S 变化规则: 交换字符串中任意两个不同位置的字符M S都是小写字符组成 1 <= S.length <= 1000 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Python)真题目录汇总 输入 一串小写字母组成的字符串 输出 按照要求变换得到…...
Word处理控件Aspose.Words功能演示:使用 Java 在 MS Word 文档中进行邮件合并
Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作任务。API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word。此外,Aspose API支持流行文件格式处理…...
产品未出 百度朋友圈“开演”
ChatGPT这股AI龙卷风刮到国内时,人们齐刷刷望向百度,这家在国内对AI投入最高的公司最终出手了,大模型新项目文心一言(ERNIE Bot)将在3月正式亮相,对标微软投资的ChatGPT。 文心一言产品未出,百…...
emacs 中的键盘宏
emacs 中的键盘宏 宏定义是emacs比较强大的功能,自定义宏然后绑定快捷键之后就更加爽了。 vim 当然也有宏功能,而且用法简单,例如录制宏到a寄存器:qa...q, 执行宏a: a 世界就是由循环和递归构成的. 宏定义就是一个执行体,为了以后的循环做准备的 开启宏记录 C-x ( 或…...
TCP/IP网络编程——关于 I/O 流分离的其他内容
完整版文章请参考: TCP/IP网络编程完整版文章 文章目录第 16 章 关于 I/O 流分离的其他内容16.1 分离 I/O 流16.1.1 2次 I/O 流分离16.1.2 分离「流」的好处16.1.3 「流」分离带来的 EOF 问题16.2 文件描述符的的复制和半关闭16.2.1 终止「流」时无法半关闭原因16.2…...
【BCT认证_组播DNS】 DNS SRV RR
每天遇见几个罕为人知的Bug,醉了 定义 关键字“必须”、“不能”、“应该”、“不应该”和“可以”本文档中使用的术语应按照 [BCP 14] 中的规定进行解释。本文档中使用的其他术语在 DNS 中定义规范,RFC 1034。 适用性声明 一般情况下,预计…...
【验证码的识别】—— 点触式验证码的识别
一、前言 大家好,不知不觉的我来csdn已经又一周年了,在这一年里,我收获了很多东西,我是2022年2月22日入驻CSDN的,一开始只是为了方便浏览文章的,后来,我也有事没事发发文章,创作了1…...
深入浅出C++ ——priority_queue类深度剖析
文章目录一、priority_queue类简介二、priority_queue类常用接口三、priority_queue类的使用四、STL中priority_queue类的模拟实现一、priority_queue类简介 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。…...
117.Android 简单的拖拽列表+防止越界拖动(BaseRecyclerViewAdapterHelper)
//1.第一步 导入依赖库和权限: //依赖库: //RecyclerView implementation com.android.support:recyclerview-v7:28.0.0//RecyclerAdapter implementation com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28 //用到的权限: <!…...
什么是Struts2?有哪些优势
Java中Strutsl是最早的基于MVC模式的轻量级Web框架,它能够合理地划分代码结构,并包含验证框架、国际化框架等多种实用工具框架。但是随着技术的进步,Struts1的局限性也越来越多地暴露出来。为了符合更加灵活、高效的开发需求,Stru…...
Ubuntu22.04 安装Mongodb6.X
Ubuntu22.04 安装Mongodb6.X 1、Mongodb简介 1.1 什么是MongoDB? Mongodb是一个跨平台的面向文档的NoSQL数据库。它使用带有可选模式的类似JSON的BSON来存储数据。应用程序可以以JSON格式检索信息。 1.2 MongoDB的优点 可以快速开发web型应用,因为灵活,…...
启动内核,能启动内核但是无法进入内核,始终卡在某一地方,比如 No soundcards found.
项目场景: 配置好uboot后,启动内核,能启动内核但是无法进入内核,始终卡在某一地方,比如下图 ALSA device list:No soundcards found.问题描述 原因分析: 这是无法进入根文件系统而出现的错误,…...
SQL零基础入门学习(六)
SQL零基础入门学习(六) SQL零基础入门学习(五) SQL 通配符 通配符可用于替代字符串中的任何其他字符。 SQL 通配符用于搜索表中的数据。 在 SQL 中,可使用以下通配符: 演示数据库 在本教程中ÿ…...
股票、指数、快照、逐笔... 不同行情数据源的实时关联分析应用
在进行数据分析时经常需要对多个不同的数据源进行关联操作,因此在各类数据库的 SQL 语言中均包含了丰富的 join 语句,以支持批计算中的多种关联操作。 DolphinDB 不仅通过 join 语法支持了对于全量历史数据的关联处理,而且在要求低延时的实时…...
华为OD机试真题Python实现【 不含 101 的数】真题+解题思路+代码(20222023)
不含 101 的数 题目 小明在学习二进制时,发现了一类不含 101 的数, 也就是将数字用二进制表示,不能出现 101 。 现在给定一个正整数区间 [l,r],请问这个区间内包含了多少个不含 101 的数? 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Python)真题目录汇…...
centos7 搭建ELK(elasticsearch、logstash、kibana)
1、下载安装包 使用华为镜像站下载速度很快,华为镜像站:https://mirrors.huaweicloud.com/home,下载时需要保证版本一致 2、安装elasticsearch 解压到当前目录 [rootlocalhost elk]# tar zxvf elasticsearch-7.4.2-linux-x86_64.tar.gz 安…...
如何写新闻稿?写好新闻稿的技巧与步骤
新闻稿是传递新闻事件和信息的重要手段,是传媒工作中不可或缺的一部分。写好一篇新闻稿可以让受众了解更多信息,进一步提高他们的关注度。以下是一些写好新闻稿的技巧和步骤,帮助你有效地传达新闻。1、确定新闻的核心信息在开始写新闻稿之前&…...
抖音不想只做“开心果”
出品 | 何玺 排版 | 叶媛 2023一开年,抖音就新动作不断。先是宣布启动线上超市,继而又传出将在3月份试水外卖业务,展现出多面出击的姿态。 01 抖音杀入线上超市、外卖赛道 抖音正式杀入“线上超市”赛道。据多家媒体报道,抖音…...
MATLAB | 如何用MATLAB绘制这样有气泡感的网络图
今天给大家带来一款用来绘制有气泡感的网络图的工具函数,绘制效果如下: 花里胡哨的,气泡大小代表流入流出数据量综合,不同颜色的气泡代表属于不同类,两个气泡之间有连线代表有数据流动,连线透明度代表流动数…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
接口 RESTful 中的超媒体:REST 架构的灵魂驱动
在 RESTful 架构中,** 超媒体(Hypermedia)** 是一个核心概念,它体现了 REST 的 “表述性状态转移(Representational State Transfer)” 的本质,也是区分 “真 RESTful API” 与 “伪 RESTful AP…...
第22节 Node.js JXcore 打包
Node.js是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境。 JXcore是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。 本文主要介绍JXcore的打包功能。 JXcore 安装 下载JXcore安装包&a…...
中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点
中科院1区顶刊|IF14:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点 当下,免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入,我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...
【字节拥抱开源】字节团队开源视频模型 ContentV: 有限算力下的视频生成模型高效训练
本项目提出了ContentV框架,通过三项关键创新高效加速基于DiT的视频生成模型训练: 极简架构设计,最大化复用预训练图像生成模型进行视频合成系统化的多阶段训练策略,利用流匹配技术提升效率经济高效的人类反馈强化学习框架&#x…...
