FreeRTOS移植到STM32

article/2025/4/27 9:38:26

一、找一个STM32的裸机工程模板

我们以STM32F103裸机程序为例

随便找的一个裸机程序

二、去官网上下载FreeRTOS V9.0.0 源码

在移植之前,我们首先要获取到 FreeRTOS 的官方的源码包。这里我们提供两个下载 链 接 , 一 个 是 官 网 : http://www.freertos.org/ , 另 外 一 个 是 代 码 托 管 网 站 : https://sourceforge.net/projects/freertos/files/FreeRTOS/。虽然不是最新版本的源码包但是因为内核很稳定, 并且网上资料很多所以我们选用V9.0.0 版本

我们打开 FreeRTOS 的代码托管网站,就可以看到 FreeRTOS 的源码及其版本信息了, 具体见图

点开V9.0.0下载zip这个,

解压完成后就会得到一个完整的Freertos源码包

FreeRTOS 包含 Demo 例程和内核源码(比较重要,我们就需要提取该目录下的大部分 文件),具体见图 13-5。FreeRTOS 文件夹下的 Source 文件夹里面包含的是 FreeRTOS 内 核的源代码,我们移植 FreeRTOS 的时候就需要这部分源代码;FreeRTOS 文件夹下的 Demo 文件夹里面包含了 FreeRTOS 官方为各个单片机移植好的工程代码,FreeRTOS 为了 推广自己,会给各种半导体厂商的评估板写好完整的工程程序,这些程序就放在 Demo 这 个目录下,这部分 Demo 非常有参考价值。我们把 FreeRTOS 到 STM32 的时候, FreeRTOSConfig.h 这个头文件就是从这里拷贝过来的,我们这里不做详解

三、往裸机工程添加 FreeRTOS 源码

1. 首 先在 我们 的 STM32 裸 机工 程模 板根 目录 下新 建一 个文 件夹, 命名 为 “FreeRTOS”,并且在 FreeRTOS 文件夹下新建两个空文件夹,分别命名为“src” 与“port”,src 文件夹用于保存 FreeRTOS 中的核心源文件,也就是我们常说的 ‘.c 文件’,port 文件夹用于保存内存管理以及处理器架构相关代码,这些代码 FreeRTOS 官方已经提供给我们的,直接使用即可,在前面已经说了,FreeRTOS 是软件,我们的开发版是硬件,软硬件必须有桥梁来连接,这些与处理器架构相 关的代码,可以称之为 RTOS 硬件接口层,它们位于 FreeRTOS/Source/Portable 文 件夹下。

2. 打开 FreeRTOS V9.0.0 源码,在“FreeRTOSv9.0.0\FreeRTOS\Source”目录下找到 所有的‘.c 文件’,将它们拷贝到我们新建的 src 文件夹中,

3. 打开 FreeRTOS V9.0.0 源码,在“FreeRTOSv9.0.0\FreeRTOS\Source\portable”目 录下找到“MemMang”文件夹与“RVDS”文件夹,将它们拷贝到我们新建的 port 文件夹中,

4. 打开 FreeRTOS V9.0.0 源码,在“FreeRTOSv9.0.0\ FreeRTOS\Source”目录下找到 “include”文件夹,它是我们需要用到 FreeRTOS 的一些头文件,将它直接拷贝 到我们新建的 FreeRTOS 文件夹中,完成这一步之后就可以看到我们新建的 FreeRTOS 文件夹已经有 3 个文件夹,这 3个文件夹就包含 FreeRTOS 的核心文件, 至此,FreeRTOS 的源码就提取完成, 

 5

 5.拷贝 FreeRTOS 到裸机工程根目录

 鉴于 FreeRTOS 容量很小,我们直接将刚刚提取的整个 FreeRTOS 文件夹拷贝到我们 的 STM32 裸机工程里面,让整个 FreeRTOS 跟随我们的工程一起发布,使用这种方法打包 的 FreeRTOS 工程,即使是将工程拷贝到一台没有安装 FreeRTOS 支持包(MDK 中有 FreeRTOS 的支持包)的电脑上面都是可以直接使用的,因为工程已经包含了 FreeRTOS 的 源码。

FreeRTOS 文件夹下就是我们提取的 FreeRTOS 的核心代码,该文件夹下的 具体内容作用,这里就不再赘述。

 6.拷贝 FreeRTOSConfig.h 文件到 user 文件夹

FreeRTOSConfig.h 文件是 FreeRTOS 的工程配置文件,因为 FreeRTOS 是可以裁剪的 实时操作内核,应用于不同的处理器平台,用户可以通过修改这个 FreeRTOS 内核的配置 头文件来裁剪 FreeRTOS 的功能,所以我们把它拷贝一份放在 user 这个文件夹下面。 打开 FreeRTOSv9.0.0 源码,在“FreeRTOSv9.0.0\FreeRTOS\Demo”文件夹下面找到 “ CORTEX_STM32F103_Keil ” 这 个 文 件 夹 , 双 击 打 开 , 在 其 根 目 录 下 找 到 这 个 “FreeRTOSConfig.h”文件,然后拷贝到我们工程的 user 文件夹下即可,

 

 7.添加 FreeRTOS 源码到工程组文件夹

在上一步我们只是将 FreeRTOS 的源码放到了本地工程目录下,还没有添加到开发环 境里面的组文件夹里面,FreeRTOS 也就没有移植到我们的工程中去。

新建 FreeRTOS/src 和 FreeRTOS/port 组,接下来我们在开发环境里面新建 FreeRTOS/src 和 FreeRTOS/port 两个组文件夹,其中 FreeRTOS/src 用于存放 src 文件夹的内容,FreeRTOS/port 用于存放 port\MemMang 文件夹 与 port\RVDS\ARM_CM?文件夹的内容,“?”表示 3、4 或者 7,具体选择哪个得看你 使用的是哪个型号的 STM32 开发板,如果是F3系列就拷贝port\RVDS\ARM_CM3

F4系列就拷贝port\RVDS\ARM_CM4,然后我们将工程文件中 FreeRTOS 的内容添加到工程中去,按照已经新建的分组添加 我们的 FreeRTOS 工程源码。 在 FreeRTOS/port 分组中添加 MemMang 文件夹中的文件只需选择其中一个即可,我 们选择“heap_4.c”,这是 FreeRTOS 的一个内存管理源码文件。同时,需要根据自己的开 发板型号在 FreeRTOS\port\RVDS\ARM_CM?中选择,“?”表示 3、4 或者 7,具体选择 哪个得看你使用的是哪个型号的 STM32 开发板。

 

然后在 user 分组中添加我们 FreeRTOS 的配置文件“FreeRTOSConfig.h”,因为这是 头文件(.h),所以需要在添加时选择文件类型为“All files (*.*)”,至此我们的 FreeRTOS 添加到工程中就已经完成,效果图如下

 8.指定 FreeRTOS 头文件的路径

 这一步不过多解释,用过STM32的人都知道

 9.FreeRTOSConfig.h 文件修改

       FreeRTOSConfig.h 头文件的内容修改的不多,具体是:修改与对应开发板的头文件 , 如果是使用野火 STM32F1 的开发板,则包含 F1 的头文件#include "stm32f10x.h",同理是 使用了其它系列的开发板,则包含与开发板对应的头文件即可,当然还需要包含我们的串 口的头文件“bsp_usart.h”,因为在我们 FreeRTOSConfig.h 中实现了断言操作,需要打印 一些信息。其他根据需求修改即可,

 10. 修改 stm32f10x_it.

SysTick 中断服务函数是一个非常重要的函数,FreeRTOS 所有跟时间相关的事情都在 里面处理,SysTick 就是 FreeRTOS 的一个心跳时钟,驱动着 FreeRTOS 的运行,就像人的 心跳一样,假如没有心跳,我们就相当于“死了”,同样的,FreeRTOS 没有了心跳,那么 它就会卡死在某个地方,不能进行任务调度,不能运行任何的东西,因此我们需要实现一 个 FreeRTOS 的心跳时钟,FreeRTOS 帮我们实现了 SysTick 的启动的配置:在 port.c 文件 中已经实现 vPortSetupTimerInterrupt()函数,并且 FreeRTOS 通用的 SysTick 中断服务函数 也实现了:在 port.c 文件中已经实现 xPortSysTickHandler()函数,所以移植的时候只需要我 们在 stm32f10x_it.c 文件中实现我们对应(STM32)平台上的 SysTick_Handler()函数即可。 FreeRTOS 为开发者考虑得特别多,PendSV_Handler()与 SVC_Handler()这两个很重要的函 数都帮我们实现了,在 port.c 文件中已经实现 xPortPendSVHandler()与 vPortSVCHandler() 函数,防止我们自己实现不了,那么在 stm32f10x_it.c 中就需要我们注释掉 PendSV_Handler()与 SVC_Handler()这两个函数了,具体看一下代码

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include "FreeRTOS.h"					//FreeRTOS使用		  
#include "task.h" 
/** @addtogroup STM32F10x_StdPeriph_Template* @{*//* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*//******************************************************************************/
/*            Cortex-M3 Processor Exceptions Handlers                         */
/******************************************************************************//*** @brief  This function handles NMI exception.* @param  None* @retval None*/
void NMI_Handler(void)
{
}/*** @brief  This function handles Hard Fault exception.* @param  None* @retval None*/
void HardFault_Handler(void)
{/* Go to infinite loop when Hard Fault exception occurs */while (1){}
}/*** @brief  This function handles Memory Manage exception.* @param  None* @retval None*/
void MemManage_Handler(void)
{/* Go to infinite loop when Memory Manage exception occurs */while (1){}
}/*** @brief  This function handles Bus Fault exception.* @param  None* @retval None*/
void BusFault_Handler(void)
{/* Go to infinite loop when Bus Fault exception occurs */while (1){}
}/*** @brief  This function handles Usage Fault exception.* @param  None* @retval None*/
void UsageFault_Handler(void)
{/* Go to infinite loop when Usage Fault exception occurs */while (1){}
}/*** @brief  This function handles SVCall exception.* @param  None* @retval None*/
//void SVC_Handler(void)
//{
//}/*** @brief  This function handles Debug Monitor exception.* @param  None* @retval None*/
void DebugMon_Handler(void)
{
}extern void xPortSysTickHandler(void);
//systick中断服务函数
void SysTick_Handler(void)
{	#if (INCLUDE_xTaskGetSchedulerState  == 1 )if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){#endif  /* INCLUDE_xTaskGetSchedulerState */  xPortSysTickHandler();#if (INCLUDE_xTaskGetSchedulerState  == 1 )}#endif  /* INCLUDE_xTaskGetSchedulerState */
}/******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************//*** @brief  This function handles PPP interrupt request.* @param  None* @retval None*/
/*void PPP_IRQHandler(void)
{
}*/

11.修改main.c里面的代码
 

#include "FreeRTOS.h"
#include "task.h"
/* 开发板硬件bsp头文件 */
#include "bsp_led.h"
#include "bsp_usart.h"int main(void)
{	//里面什么都不做
}

修改好后编译看看有没有错误

笔者这是没有任何问题的。

本篇内容参考野火的Freertos内核实现与应用开发指南,详细代码可以去野火官方下载中心下载查看https://doc.embedfire.com/products/link/zh/latest/index.html


http://chatgpt.dhexx.cn/article/koCbYMHP.shtml

相关文章

韦东山freeRTOS系列教程之【第一章】FreeRTOS概述与体验

文章目录 教程目录1.1 FreeRTOS目录结构1.1 FreeRTOS目录结构1.2 核心文件1.3 移植时涉及的文件1.4 头文件相关1.4.1 头文件目录1.4.2 头文件 1.5 内存管理1.6 Demo1.7 数据类型和编程规范1.7.1 数据类型1.7.2 变量名1.7.3 函数名1.7.4 宏的名 1.8 安装Keil1.8.1 下载Keil1.8.2…

freeRTOS中文实用教程1

资料转载出处 https://www.cnblogs.com/smartjourneys/p/7073450.html 1.前言 FreeRTOS是小型多任务嵌入式操作系统,硬实时性。本章主要讲述任务相关特性及调度相关的知识。 任务的总体特点 任务的状态 (1)任务有两个状态,运行态…

FreeRTOS入门

目录 一、简介 二、堆的概念 三、栈的概念 四、从官方源码中精简出第一个FreeRTOS程序 五、修改官方源码增加串口打印 一、简介 FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、…

freeRTOS系列教程之【第一章】FreeRTOS概述与体验

文章目录 教程目录1.1 FreeRTOS目录结构1.1 FreeRTOS目录结构1.2 核心文件1.3 移植时涉及的文件1.4 头文件相关 1.4.1 头文件目录1.4.2 头文件 1.5 内存管理1.6 Demo1.7 数据类型和编程规范 1.7.1 数据类型1.7.2 变量名1.7.3 函数名1.7.4 宏的名 1.8 安装Keil 1.8.1 下载Keil1.…

【机器学习】3-4-2 流行学习

#3-4-2流行学习 import mglearn import numpy as np import matplotlib.pyplot as plt import pandas as pd from sklearn.datasets import load_breast_cancer from sklearn.datasets import make_moons from sklearn.datasets import make_blobs from sklearn.datasets impor…

【机器学习】(十八)用t-SNE进行流行学习:手写数字分类

PCA是用于变换数据的首选方法,也可以进行可视化,但它的性质(先旋转然后减少方向)限制了有效性。 流行学习算法:是一类用于可视化的算法,它允许进行更复杂的映射,通常也可以给出更好的可视化。t-…

用Python实现流行机器学习算法

对于此库的Octave/MatLab版本,请检查machine-learning-octave项目。 该库包含在Python中实现的流行机器学习算法的示例,其中包含数学背后的解释。 每个算法都有交互式Jupyter Notebook演示,允许您使用训练数据,算法配置&#xff0…

【流行学习】局部线性嵌入(Locally Linear Embedding)

一、前言 局部线性嵌入(LLE)假设数据在较小的局部是线性的,也就是说,某一个样本可以由它最近邻的几个样本线性表示,离样本远的样本对局部的线性关系没有影响,因此相比等距映射算法,降维的时间复…

流行-Manifold学习理解与应用

流行-Manifold【1】 流形,也就是 Manifold 。 1. 比较好的形象理解 流形学习的观点是认为,我们所能观察到的数据实际上是由一个低维流形映射到高维空间上的,即这些数据所在的空间是“嵌入在高维空间的低维流形。”。由于数据内部特征的限制&a…

【流行学习】拉普拉斯映射(Laplacian Eigenmaps)

一、前言 拉普拉斯特征映射是一种基于图的降维算法,它希望在原空间中相互间有相似关系的点,在降维后的空间中尽可能的靠近,从而在降维后仍能保持原有的数据结构信息。 二、主要步骤 拉普拉斯特征映射通过构建邻接矩阵为 W W W(…

7个流行的强化学习算法及代码实现

目前流行的强化学习算法包括 Q-learning、SARSA、DDPG、A2C、PPO、DQN 和 TRPO。 这些算法已被用于在游戏、机器人和决策制定等各种应用中,并且这些流行的算法还在不断发展和改进,本文我们将对其做一个简单的介绍。 1、Q-learning Q-learning&#xff1…

流行学习,比较好的一篇博客

转载自:https://blog.csdn.net/sinat_32043495/article/details/78997758 嵌入在高维空间的低维流形 流形:局部具有欧几里得空间性质的空间 1.较好的描述转载 作者:暮暮迷了路 链接:https://www.zhihu.com/question/2401548…

深度学习—近年来流行的卷积神经网络(一)

近年来流行的卷积神经网络 1. 回顾与目标2. 近年来流行的卷积神经网络2.1 VGGNet2.1.1 感受野的概念2.1.2 感受野的计算 2.2 GooleNet2.3 ResNet 3. 结尾参考资料 1. 回顾与目标 前面几讲,我们以LeNet和AlexNet为例,详细讲解了卷积神经网络的结构。从20…

流行学习常用算法

Isomap:等距映射。前提假设为低维空间中的欧式距离等于高维空间中的侧地线距离,当然该算法具体实施时是高维空间中较近点之间的测地线距离用欧式距离代替,较远点距离用测地线距离用最短路径逼近。 LLE:局部线性嵌入。前提假设是数据所在的低维…

流行学习与拉普拉斯变换的推导

参考:拉普拉斯矩阵 参考:流行学习

流行学习初步理解

一. 流形学习的英文名为manifold learning。其主要思想是把一个高维的数据非线性映射到低维,该低维数据能够反映高维数据的本质,当然有一个前提假设就是高维观察数据存在流形结构,其优点是非参数,非线性,求解过程简单。…

流行学习简单入门与理解

最近博主再看西瓜书第十三章半监督学习,文章中作者提到需要少量查询的主动学习、K-means簇的聚类,以及流行学习。对于流行学习,博主也是第一次接触,下面我们来简单学习和理解一下流行学习。 1. 半监督学习 SSL的成立依赖于模型假…

机器学习----流行学习(manifold learning)的通俗理解

流形学习(manifold learning)是一类借鉴了拓扑流行概念的降维方法,在降维时,若低维流行嵌入到高维空间中,则数据样本在高维空间的分布虽然看上去十分复杂,但在局部上仍具有欧式空间(对现实空间的…

流行学习Manifold Learning

文章目录 1、流行学习前言:2、流形学习的概念流形的概念:流行学习的概念: 3、流形学习的分类4、高维数据降维与可视化5、基本问题和个人观点6、参考文献 1、流行学习前言: 流形学习是个很广泛的概念。这里我主要谈的是自从2000年…

关于nn.embedding的理解

import torch.nn as nn nn.Embedding(num_embeddings, embedding_dim, padding_idxNone, max_normNone, norm_type2, scale_grad_by_freqFalse, sparseFalse)参数解释 num_embeddings (python:int) – 词典的大小尺寸,比如总共出现5000个词,那就输入500…