STM32之FreeRTOS移植(重点)
- RTOS的基本概念
实时操作系统(Real Time Operating System)的简称就叫做RTOS,是指具有实时性、能支持实时控制系统工作的操作系统,RTOS的首要任务就是调度所有可以利用的资源来完成实时控制任务的工作,其次才是提高工作效率。
绝大多数比较简单的产品(中小型产品)是直接在单片机上“裸奔”的,也就是产品不需要搭载RTOS的,但是产品的各个功能想要正常工作都需要主程序来进行调度。
其实RTOS就是一段嵌入在程序中的代码,在系统上电复位后首先被执行,可以理解为用户的主程序,只不过用户把产品的其他功能(子程序)都建立在RTOS之上,在RTOS中可以调用API函数为每个子程序都创建一个任务(也可以叫做线程),用户只需要调用RTOS内核中的相关的API函数接口就可以控制子程序,而且可以为每个任务设置不同的优先级,通过RTOS的调度器进行调度,这样就可以合理的使用CPU。
这里就涉及到产品的设计思路(裸机开发 or RTOS)以及程序的运行方式,可以分为三种:
- 轮询式
轮询系统指的是程序运行时,先初始化各种硬件,初始化硬件之后程序进入一个死循环中,按照事件的顺序进行执行,该系统的结构非常简单,只适用于按照顺序执行事件并且没有外部事件来打断的情况,轮询系统就非常可靠,但是一旦有外部事件或者外部需要检测的信号来打断,则会造成外部事件的缺失。
int main(){//硬件的初始化while(1){//事件1 LED//事件2 BEEP//....... KEY}}
- 前后台
前后台系统就是在轮询系统的基础上增加了中断,进行外部事件检测的时候就在中断中实现,所以中断也被称为前台,而其他事件还是在主程序的死循环中按照顺序执行,一旦中断发生,则会暂停执行后台的while(1),然后去执行前台的中断服务函数,如果事件简短,直接在中断中实现,如果事件复杂,则返回主程序的死循环实现,该方案可以提高程序的实时响应能力。
int main(){//硬件的初始化//注册中断,设置中断的触发条件while(1){//事件1//事件2.....}}//中断服务函数void XXX_IRQ (void){//执行中断的事件//执行完成返回main函数}
- 多任务
多任务系统指的是在前后台系统的基础上执行外部事件,只不过外部事件是放在任务中执行,不在中断服务函数中执行,一旦某个外部事件满足触发条件,就在中断服务函数中设置事件标志,然后在跳转到任务中执行事件,任务分优先级的,优先级高的任务就先执行,所以程序就会被分割为一个个的任务(不能退出),每个任务都有一个独立的函数来执行的功能。更大程序提高程序的实时性。
void task1(void *arg){while(1){//LED}}void task2(void *arg){while(1){//BEEP}}int main(){//硬件的初始化//注册中断,设置中断的触发条件//注册任务,根据任务调度器进行调度}
- RTOS的种类
RTOS是实时操作系统的统称,不意味着是某一种确定的操作系统,而是指某一类操作系统,比如最常用的uC/OSII、uC/OSIII、FreeRTOS、RTX、RT-Thread、Huawei LiteOS........每种RTOS各有特色,所以大家可以根据实际需要选择对应的RTOS进行学习。
- uC/OS
uC/OS是Micrium公司推出的RTOS实时操作系统,分为两个版本: uC/OSII 和 uC/OSIII,该RTOS的特点是开源的、可裁剪的、具有可剥夺型内核,uC/OSII可以支持创建最多255个任务,而uC/OSIII对任务数量没有限制。
uC/OS的发布时间是较早的,所以中文资料是最多的,并且代码例程比较丰富,但是想要在商业中进行使用,需要取得正版授权(花钱),所以大家可以把UCOS作为RTOS的入门。关于uC/OS的资料和源码都可以去官网下载 官网地址:www.micrium.com
- FreeRTOS
FreeRTOS也是RTOS的一种,在2003年发布,是免费的,虽然起步比UCOS晚,但是由于可以在商业中免费使用,所以目前的市场占有率是最高的,并且很多的半导体公司都和FreeRTOS有很紧密的合作关系,这些半导体公司的评估板绝大多数都是采用FreeRTOS进行程序设计。比如半导体公司发布的SDK(开发工具包)一般也采用FreeRTOS,另外,像蓝牙、WIFI等带协议栈的芯片或者模块也是采用FreeRTOS。
相比于UCOS而言,FreeRTOS的文件数量更少,占用内存空间更少,所以在移植到不同硬件平台的时候更加轻松,FreeRTOS对于任务数量也是没有限制的,而是对于任务的优先级也没有限制。
FreeRTOS支持抢占式、时间片调度等算法,而且FreeRTOS是完全免费的,这也是FreeRTOS的核心竞争力。
FreeRTOS可以用在商业领域,不具有版权问题,如果在产品中使用FreeRTOS时没有修改原码,则产品不需要开源,如果使用FreeRTOS的过程修改了原码,则需要把修改的那部分代码进行开源,遵循MIT开源协议。
大家可以去FreeRTOS的官网下载源码以及其他的资料,比如FreeRTOS提供了若干本书籍,比如关于RTOS的API函数的参考手册以及新手教程。 官网地址:www.freertos.org
- RT-Thread
长期作业:自行观看RT-Thread的相关视频和教程,要求大家可以自行完成Rt-thread的移植。
- RTOS的源码下载
想要真正掌握RTOS,则必须要去阅读RTOS的源码,才能理解RTOS是如何对任务进行调度
可以去FreeRTOS的官网下载源码。
- 点击选项链接跳转GitHub托管网站,下载FreeRTOS以前的发行源码包, 比如 V9.0.0
- 点击GitHub的标签tags,显示所有的FreeRTOS的源码发行版,搜索到V9.0.0版本即可
注意:如果浏览器在登录GitHub网站时等待时间过长,或者无法登录界面,则可以使用其他的代码托管网站进行源码下载,比如Sourceforge代码托管网站 ,搜索FreeRTOS即可。
- RTOS源码结构
解压好的源码包内部有一个叫做FreeRTOS的文件夹,该文件夹内部包含FreeRTOS的源码以及许可和通用的头文件,并且还提供丰富的案例供用户在不同的硬件平台使用。
Demo中提供了很多个半导体公司的评估板的代码例程,用户可以参考甚至直接使用。而License文件夹中包含了FreeRTOS的许可文件,大家可以在商业软件中进行参考,在Source文件夹中包含通用的头文件以及针对不同硬件平台的移植文件供用户使用。
五、FreeRTOS的移植
如果想要在项目中利用RTOS对任务进行调度,则需要把RTOS的源码移植到自己的项目中,移植的步骤如下:
- 去FreeRTOS的官网下载源码包,源码包的版本可以是V9.0.0或更新的版本 (比较稳定)
- 把源码包解压到本地,分析源码包中哪些文件需要移植,可以浏览源码包的readme.txt
- 把FreeRTOS源码包中需要移植的文件拷贝到自己工程中对应的文件夹,操作如下所示:
- 打开自己的工程,把拷贝过来文件添加到KEIL5工程中,编辑文件夹的结构,如下所示
- 配置KEIL5工程的头文件的路径,确保编译器可以找到关于FreeRTOS的头文件,如下:
- 编译工程,如果编译之后报错,根据错误原因解决错误,直到编译通过为止,如下所示
- 提示:__ICCARM__宏定义是和开发工具相关的,该宏定义是IAR软件需要使用的,而目前采用的开发工具是KEIL,KEIL软件需要使用其他的宏定义。
再次编译,发现有函数出现重复定义的情况,port.c和stm32f4xx_it.c中出现,所以可以选择分别进行分析,可以把stm32f4xx_it.c中的函数名称删除即可。
再次编译,发现有5个函数未定义,命名规则是有规律的,都是HooK结尾,Hook是钩子函数,其实属于回调函数的一种,目前由于不知道是否需要使用,可以选择不去定制。
由于FreeRTOS是高度可定制的,定制的功能是由FreeRTOSConfig.h决定,所以需要配置该头文件,裁剪掉这几个功能即可。
再次编译,发现没有出现任何错误和任何警告,则说明FreeRTOS实时操作系统移植成功!!
五、FreeRTOS的任务管理
- 任务的概念
FreeRTOS是一个支持多任务的实时操作系统,如之前裸机开发时采用的轮询系统而言,主程序是一个死循环,CPU按照死循环中的流程执行代码,而在多任务系统中,用户可以把整个系统分割为多个独立的且不能返回(死循环)的函数,这些函数就被称为任务。
应用程序中的任务都是由FreeRTOS的调度器进行调度,同时每个任务具有独立的栈空间,栈空间其实就是单片机中RAM的一段空间,通常可以提前定义一个全局数组,或者在创建任务的时候对任务的栈空间进行动态的分配,可以参考FreeRTOS的官方资料。
- 任务的状态
对于FreeRTOS中的任务而言,FreeRTOS的调度器会根据任务的状态决定运行哪个任务,任务的状态一共有四种:运行态、就绪态、挂起态、阻塞态。 可以参考FreeRTOS的官网资料。
- 任务优先级
FreeRTOS可以为每一个创建的任务分配一个优先级,当然也可以让多个任务共用一个优先级,这里就涉及到调度器的调度算法,有抢占式、时间片一共2种算法。
- 任务的创建
刚才提到过任务都是独立的,并且每个任务都需要占用一部分RAM空间,单片机中的RAM是有限的,所以FreeRTOS就提供了两种方案为每个任务分配栈空间:静态分配 + 动态分配,而且FreeRTOS提供了不同的函数接口给用户去申请任务的空间。两种分配方案的区别如下:
一般情况下采用动态分配的方案,所以需要调用API函数,名字叫做xTaskCreate(),如下图
- 启动调度器
- 任务的删除
FreeRTOS中的任务是可以删除的,如果用户创建的任务只打算运行一次就可以删掉,调用函数接口 vTaskDelete() ,调用该函数就可以把动态创建或者静态创建的任务从任务表中删掉。
- 任务的挂起
在某些情况下,某些任务可能只运行一段时间,然后让任务暂停运行,过一段时间继续运行,如果采用反复删除和反复创建的方案,就会导致任务之前的数据丢失,FreeRTOS提供一个函数可以把任务挂起,该函数为vTaskSuspend() 。
一旦任务被挂起,则不管任务的优先级是否为最高,都不会获得CPU资源,也就是说处于挂起态的任务永远不能进入运行态,除非该任务被恢复,如果想要恢复一个任务,则需要调用vTaskResume()。
- 任务的恢复
FreeRTOS提供了一个恢复函数,可以让处于挂起态的任务恢复,注意只有被挂起的任务才可以被恢复。
相关文章:

STM32之FreeRTOS移植(重点)
RTOS的基本概念 实时操作系统(Real Time Operating System)的简称就叫做RTOS,是指具有实时性、能支持实时控制系统工作的操作系统,RTOS的首要任务就是调度所有可以利用的资源来完成实时控制任务的工作,其次才是提高工…...
做好测试用例设计工作的关键是什么?
测试用例设计是软件测试的核心环节,好的测试用例能高效发现缺陷,差的测试用例则可能漏测关键问题。结合多年测试经验,我认为做好测试用例设计的关键在于以下6点: 1. 深入理解需求(核心基础) ✅ 关键点: 与产品经理/开发对齐,确保理解无偏差(避免“我以为”式测试) 拆…...

R语言科研编程-标准偏差柱状图
生成随机数据 在R中,可以使用rnorm()生成正态分布的随机数据,并模拟分组数据。以下代码生成3组(A、B、C)随机数据,每组包含10个样本: set.seed(123) # 确保可重复性 group_A <- rnorm(10, mean50, sd…...
未来教育考试答题软件4.0【自用链接备份】
未来教育考试答题软件4.0【自用链接备份】 http://www.downyi.com/downinfo/240413.html 补丁地址:https://www.wodown.com/soft/43108.html...

OpenGL Chan视频学习-11 Uniforms in OpenGL
bilibili视频链接: 【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p5&vd_source44b77bde056381262ee55e448b9b1973 函数网站: docs.gl 说明: 1.之后就不再单独整理网站具体函数了,网站直接翻译…...
Flink系列文章列表
把写的文章做一个汇总,会陆续更新的。 Flink流处理原理与实践:状态管理、窗口操作与容错机制-CSDN博客...

GitLab 从 17.10 到 18.0.1 的升级指南
本文分享从 GitLab 中文本 17.10.0 升级到 18.0.1 的完整过程。 升级前提 查看当前安装实例的版本。有多种方式可以查看: 方式一: /help页面 可以直接在 /help页面查看当前实例的版本。以极狐GitLab SaaS 为例,在浏览器中输入 https://ji…...

产业集群间的专利合作关系
需要准备的文件: 全国的专利表目标集群间的企业名单 根据专利的共同申请人,判断这两家企业之间存在专利合作关系。 利用1_filter_patent.py,从全国的3000多万条专利信息中,筛选出与目标集群企业相关的专利。 只要专利的申请人包…...
PyQt学习系列02-模型-视图架构与数据管理
PyQt学习系列笔记(Python Qt框架) 第二课:PyQt的模型-视图架构与数据管理 一、模型-视图架构概述 1.1 什么是模型-视图架构? 模型-视图(Model-View)是Qt框架中用于数据展示和交互的核心设计模式。它将数…...
redis主从复制架构安装与部署
redis主从复制架构安装与部署 1、Redis 一主两从架构的优势2、环境准备3、下载redis4、解压缩文件5、编辑配置文件6、创建数据目录并启动Redis7、检查主从状态8、 Redis Sentinel 模式 1、Redis 一主两从架构的优势 Redis 采用一主两从(1个主节点 2个从节点&#…...
Kotlin 中 Lambda 表达式的语法结构及简化推导
在 Kotlin 编程中,Lambda 表达式是一项非常实用且强大的功能。今天,我们就来深入探讨一下 Lambda 表达式的语法结构,以及它那些令人 “又爱又恨” 的简化写法。 一、Lambda 表达式完整语法结构 Lambda 表达式最完整的语法结构定义为{参数名…...
YOLOv2 深度解析:目标检测领域的进阶之路
在计算机视觉领域,目标检测一直是研究和应用的热点方向。YOLO(You Only Look Once)系列算法以其快速高效的特点,在目标检测领域占据了重要地位。YOLOv2 作为 YOLO 系列算法的重要迭代版本,在 YOLOv1 的基础上进行了诸多…...

KT6368A通过蓝牙芯片获取手机时间详细说明,对应串口指令举例
一、功能简介 KT6368A双模蓝牙芯片支持连接手机,获取手机的日期、时间信息,可以同步RTC时钟 1、无需安装任何app,直接使用系统蓝牙即可实现 2、同时它不影响音频蓝牙,还支持一些简单的AT指令进行操作 3、实现的方式࿱…...

计算机网络实验课(二)——抓取网络数据包,并实现根据条件过滤抓取的以太网帧,分析帧结构
文章目录 一、添加控件二、代码分析2.1 代码2.2 控件初始化2.3 打开和关闭设备2.4 开始和结束捕获2.5 设置捕获条件2.6 捕获数据包 三、运行程序四、结果分析 提要:如果你通过vs打开.sln文件,然后代码界面或者前端界面都没找到,视图里面也没找…...
自动生成提示技术突破:AUTOPROMPT重塑语言模型应用
AUTOPROMPT 预训练语言模型的显著成功促使人们研究这些模型在预训练期间学习了哪些类型的知识。将任务重新表述为填空题(例如,完形填空测试)是衡量此类知识的自然方法 但是,它的使用受到编写合适提示所需的手动工作和猜测的限制。为了解决这个问题,我们开发了 AUTOPROMP…...

78. Subsets和90. Subsets II
目录 78.子集 方法一、迭代法实现子集枚举 方法二、递归法实现子集枚举 方法三、根据子集元素个数分情况收集 方法四、直接回溯法 90.子集二 方法一、迭代法实现子集枚举 方法二、递归法实现子集枚举 方法三、根据子集元素个数分情况收集 方法四、直接回溯法 78.子集…...
VSCode 插件 GitLens 破解方法
文章目录 1. 安装指定版本2. 修改插件文件3. 重启 VSCode 1. 安装指定版本 在 VSCode 中打开扩展(Ctrl Shift X),搜索 GitLens,右键点击 安装特定版本,在弹出的窗口中选择 17.0.2,然后等待安装完成。 2…...
linux 通过命令将 MinIO 桶的权限设置为 Custom(自定义策略)
在 Ubuntu 下,如果要通过命令将 MinIO 桶的权限设置为 Custom(自定义策略),可以使用 mc(MinIO Client)、AWS CLI 或直接调用 MinIO API(如 curl)。以下是几种方法: 方法 …...
模型评价指标介绍
模型评价指标介绍 **在机器学习与数据科学领域,构建模型仅是工作的一部分,更为关键的是要精准评估模型的性能。模型评价指标作为衡量模型表现的标准,有助于数据科学家、分析师等从业者判断模型的优劣,进而进行优化与改进。不同类…...

ElasticSearch整合SpringBoot
ElasticSearch 整合SpringBoot ES官方提供了各种不同语言的客户端。用来操作ES。这些客户端的本质就是组装DSL语句,通过HTTP请求发送给ES。 设计索引库 跟据数据库的表结构进行ES索引库的创建时。如果字段需要进行倒排索引的时候请为它指定分词器。如果该字段不是…...
ArcGIS Pro 3.4 二次开发 - 知识图谱
环境:ArcGIS Pro SDK 3.4 + .NET 8 文章目录 知识图谱1 知识图谱数据存储1.1 打开与知识图谱的连接1.2 从KnowledgeGraphLayer获取连接1.3 检索GDB要素类和定义1.4 检索GDB表和定义1.5 从知识图谱数据存储中获取服务 Uri1.6 将一组对象ID转换为实体的ID1.7 将一组ID转换为实体…...

2025上半年软考高级系统架构设计师经验分享
笔者背景 笔者在成都工作近7年, 一直担任研发大头兵,平日工作主要涵盖应用开发(Java)与数仓开发,对主流数据库、框架等均有涉猎,但谈不上精通。 最近有一些职业上的想法,了解到软考有那么一丁点…...

uni-app学习笔记十二-vue3中创建组件
通过组件,可以很方便地实现页面复用,减少重复页面的创建,减少重复代码。一个页面可以引入多个组件。下面介绍在HBuilder X中创建组件的方法: 一.组件的创建 1.选中项目,右键-->新建目录(文件夹),并将文…...
React 虚拟dom
虚拟dom react核心机制 内存中轻量级JS对象树模拟真实DOM,主要目的是减少操作真实dom的开销 具体是通过diff算法计算最小的变更,批处理更新真实dom元素 diff算法 特点 同级去进行比较,不涉及跨层的一个比较 使用key值优化列表遍历过程 …...
互联网大厂Java求职面试:AI与大模型应用集成中的架构难题与解决方案-1
互联网大厂Java求职面试:AI与大模型应用集成中的架构难题与解决方案-1 场景描述 郑薪苦,一个看似不靠谱但技术潜力巨大的程序员,在一次针对AI与大模型应用集成的面试中,被一位技术总监级别的人物提问。面试官以严肃专业的态度&a…...
《算法笔记》13.2小节——专题扩展->树状数组(BIT) 问题 D: 数列-训练套题T10T3
数列(sequence.pas/c/cpp) - 问题描述 一个简单的数列问题:给定一个长度为n的数列,求这样的三个元素ai, aj, ak的个数,满足ai < aj > ak,且i < j < k。 - 输入数据 第一行是一个整数n(n < 50000)。 第二行n个整…...

一键启动多个 Chrome 实例并自动清理的 Bash 脚本分享!
目录 一、📦 脚本功能概览 二、📜 脚本代码一览 三、🔍 脚本功能说明 (一)✅ 支持批量启动多个 Chrome 实例 (二)✅ 每个实例使用独立用户数据目录 (三)✅ 启动后自…...

4 月 62100 款 App 被谷歌下架!环比增长 28%
大家好,我是牢鹅!上周刚刚结束的 2025 年 Google I/O 开发者大会, Google Play 带来了一系列的更新,主要围绕提升优质 App 的"发现"、"互动"和"收入"三大核心内容。 这或许正是谷歌生态的一个侧影…...
图像分割全路线学习(结合论文)
本篇文章参考自开源大佬的文章并结合自己的思考而来,欢迎大家提出意见,论文代码同样来自开源,文中已注明 文章目录 图像分割图像分割算法分类?传统的基于CNN的分割方法缺点?FCN详解FCN改变了什么?FCN网络结构&#x…...
Go语言之定义结构体(Struct)-《Go语言实战指南》
结构体(struct)是 Go 中的一种复合数据类型,它允许你将多个不同类型的字段组合成一个类型,类似于 C 语言的结构体或面向对象语言中的类。 一、结构体的基本定义 type 结构体名 struct {字段名 字段类型... } 示例: …...