STM32之FreeRTOS移植(重点)

  1. 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(){//硬件的初始化//注册中断,设置中断的触发条件//注册任务,根据任务调度器进行调度}
  1. RTOS的种类

RTOS是实时操作系统的统称,不意味着是某一种确定的操作系统,而是指某一类操作系统,比如最常用的uC/OSII、uC/OSIIIFreeRTOS、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的移植。

  1. RTOS的源码下载

想要真正掌握RTOS,则必须要去阅读RTOS的源码,才能理解RTOS是如何对任务进行调度

可以去FreeRTOS的官网下载源码。

  1. 点击选项链接跳转GitHub托管网站,下载FreeRTOS以前的发行源码包, 比如 V9.0.0

  1. 点击GitHub的标签tags,显示所有的FreeRTOS的源码发行版,搜索到V9.0.0版本即可

注意:如果浏览器在登录GitHub网站时等待时间过长,或者无法登录界面,则可以使用其他的代码托管网站进行源码下载,比如Sourceforge代码托管网站 ,搜索FreeRTOS即可。

  1. RTOS源码结构

解压好的源码包内部有一个叫做FreeRTOS的文件夹,该文件夹内部包含FreeRTOS的源码以及许可和通用的头文件,并且还提供丰富的案例供用户在不同的硬件平台使用。

Demo中提供了很多个半导体公司的评估板的代码例程,用户可以参考甚至直接使用。而License文件夹中包含了FreeRTOS的许可文件,大家可以在商业软件中进行参考,在Source文件夹中包含通用的头文件以及针对不同硬件平台的移植文件供用户使用。

五、FreeRTOS的移植

如果想要在项目中利用RTOS对任务进行调度,则需要把RTOS的源码移植到自己的项目中,移植的步骤如下:

  1. 去FreeRTOS的官网下载源码包,源码包的版本可以是V9.0.0或更新的版本 (比较稳定)

  1. 把源码包解压到本地,分析源码包中哪些文件需要移植,可以浏览源码包的readme.txt

  1. 把FreeRTOS源码包中需要移植的文件拷贝到自己工程中对应的文件夹,操作如下所示:

  1. 打开自己的工程,把拷贝过来文件添加到KEIL5工程中,编辑文件夹的结构,如下所示

  1. 配置KEIL5工程的头文件的路径,确保编译器可以找到关于FreeRTOS的头文件,如下:

  1. 编译工程,如果编译之后报错,根据错误原因解决错误,直到编译通过为止,如下所示

  • 提示:__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提供了一个恢复函数,可以让处于挂起态的任务恢复,注意只有被挂起的任务才可以被恢复。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/83074.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL connection close 后, mysql server上的行为是什么

本文着重讲述的是通过 msql client 连接到 mysql server ,发起 update 、 select 操作(由于数据量非常大,所以 update、select 操作都很耗时,即在结果返回前我们有足够的时间执行一些操作) 。 在客户端分别尝试执行 ctrl C 结束关闭 mysql c…

dvwa3——CSRF

LOW: 先尝试change一组密码:123456 修改成功,我们观察上面的url代码 http://localhost/DVWA/vulnerabilities/csrf/?password_new123456&password_conf123456&ChangeChange# 将password_new部分与password_conf部分改成我们想要的…

Linux 中常见的安全与权限机制

Linux 中常见的安全与权限机制主要包括以下几类,从文件系统权限到系统级访问控制,构建了多层次的安全保障体系。 🔐 一、文件权限与用户管理 1. 基本权限(rwx) r(read):读取文件内…

CSS篇-3

1. CSS 中哪些样式可以继承?哪些不可以继承? 可继承的样式: 与字体相关的样式,如:font-size、font-family、color 列表样式:list-style(如 UL、OL 的 list-style-type) 不可继承…

计算机网络物理层基础练习

第二章 物理层 填空题 从通信双方信息交互的方式来看,通信的三种基本方式为单工、半双工和全双工。其中,单工数据传输只支持数据在一个方向上传输,全双工数据传输则允许数据同时在两个方向上传输。最基本的带通调制方法包括三种&#xff1a…

Redis7底层数据结构解析

redisObject 在 Redis 的源码中,Redis 会将底层数据结构(如 SDS、hash table、skiplist 等)统一封装成一个对象,这个对象叫做 redisObject,也简称 robj。 typedef struct redisObject {unsigned type : 4; // 数…

华为OD机试_2025 B卷_静态扫描(Python,100分)(附详细解题思路)

题目描述 静态扫描可以快速识别源代码的缺陷,静态扫描的结果以扫描报告作为输出: 1、文件扫描的成本和文件大小相关,如果文件大小为N,则扫描成本为N个金币 2、扫描报告的缓存成本和文件大小无关,每缓存一个报告需要…

【Java】在 Spring Boot 中连接 MySQL 数据库

在 Spring Boot 中连接 MySQL 数据库是一个常见的任务。Spring Boot 提供了自动配置功能,使得连接 MySQL 数据库变得非常简单。以下是详细的步骤: 一、添加依赖 首先,确保你的pom.xml文件中包含了 Spring Boot 的 Starter Data JPA 和 MySQ…

基于51单片机的音乐盒键盘演奏proteus仿真

地址: https://pan.baidu.com/s/1tZCAxQQ7cvyzBfztQpk0UA 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C51 是一款常用的 8 位单片机,由 Atmel 公司(现已被 Microchip 收…

Android Native 之 adbd进程分析

目录 1、adbd守护进程 2、adbd权限降级 3、adbd命令解析 1)adb shell 2)adb root 3)adb reboot 4、案例 1)案例之实现不需要执行adb root命令自动具有root权限 2)案例之实现不需要RSA认证直接能够使用adb she…

C语言进阶--动态内存管理

学习数据结构重要的三个部分:指针、结构体、动态内存管理(malloc、calloc、realloc、free)。 1.为什么存在动态内存分配? 1.空间开辟大小是固定的; 2.数组在声明时,必须指定数组的长度,它所需…

C# 密封类和密封方法

密封(sealed)是C#中用于限制继承和多态行为的关键字,它可以应用于类和方法,提供了一种控制继承层次的方式。 密封类 特点 使用 sealed 关键字修饰的类密封类不能被其他类继承,但可以继承其他类或接口主要用于防止派生所有结构(struct)都是…

thinkpad T-440p 2025.05.31

thinkpad T-440p 2025.05.31 老了退休了,说起来真的可恶现在笔记本的设计师,只有固态硬盘了

WPS自动换行

换行前 换行后 快捷键 第一步:启用「自动换行」功能 选中目标单元格/区域:点击需要设置的单元格(或拖动选中多个单元格)。开启自动换行(3种方式任选): 快捷按钮:在顶部菜单栏点击「…

cuda_fp8.h错误

现象: cuda_fp8.h错误 原因: CUDA Toolkit 小于11.8,会报fp8错误,因此是cuda工具版本太低。通过nvcc --version查看 CUDA Toolkit 是 NVIDIA 提供的一套 用于开发、优化和运行基于 CUDA 的 GPU 加速应用程序的工具集合。它的核心作用是让开发…

【TTS】基于GRPO的流匹配文本到语音改进:F5R-TTS

论文地址:https://arxiv.org/abs/2504.02407v3 摘要 我们提出了F5R-TTS,这是一种新颖的文本到语音(TTS)系统,它将群体相对策略优化(GRPO)集成到基于流匹配的架构中。 通过将流匹配TTS的确定性输出重新表述为概率高斯分布,我们的方…

头歌java课程实验(Java面向对象 - 包装类)

第1关:基本数据类型和包装类之间的转换 任务描述 本关任务:实现基本数据类型与包装类之间的互相转换。 相关知识 为了完成本关任务,你需要掌握: 1.什么是包装类; 2.怎么使用包装类。 什么是包装类 在JAVA中&#x…

实现一个免费可用的文生图的MCP Server

概述 文生图模型为使用 Cloudflare Worker AI 部署 Flux 模型,是参照视频https://www.bilibili.com/video/BV1UbkcYcE24/?spm_id_from333.337.search-card.all.click&vd_source9ca2da6b1848bc903db417c336f9cb6b的复现Cursor MCP Server实现是参照文章https:/…

ES6 深克隆与浅克隆详解:原理、实现与应用场景

ES6 深克隆与浅克隆详解:原理、实现与应用场景 一、克隆的本质与必要性 在 JavaScript 中,数据分为两大类型: 基本类型:Number、String、Boolean、null、undefined、Symbol、BigInt引用类型:Object、Array、Functio…

新闻数据加载(鸿蒙App开发实战)

本案例基于ArkTS的声明式开发范式,介绍了数据请求和onTouch事件的使用。包含以下功能: 数据请求。列表下拉刷新。列表上拉加载。 网络数据请求需要权限:ohos.permission.INTERNET 一、案例效果截图 操作说明: 点击应用进入主页…