STM32 FreeRTOS移植

devtools/2025/1/14 19:26:49/

目录

FreeRTOS源码结构介绍

获取源码

1、 官网下载

2、 Github下载

源码结构介绍

源码整体结构

FreeRTOS文件夹结构

Source文件夹结构如下

portable文件夹结构

RVDS文件夹

MemMang文件夹 

FreeRTOS在基于寄存器项目中移植步骤

目录添加源码文件

工程添加源码文件

系统配置文件修改

main.c中添加如下代码

FreeRTOS在基于HAL库项目中移植步骤

目录添加源码文件

工程添加源码文件

系统配置文件修改

stm32f1xx_it.c-toc" style="margin-left:80px;">修改stm32f1xx_it.c

引入头文件

系统配置文件说明

FreeRTOS数据类型

TickType_t

BaseType_t

UBaseType_t

StackType_t

FreeRTOS的命名规范

变量

函数


FreeRTOS源码结构介绍

获取源码

1、 官网下载

官网地址:FreeRTOS™ - FreeRTOS™

2、 Github下载

Github地址:https://github.com/FreeRTOS/FreeRTOS/releases

源码结构介绍

源码整体结构

名称

描述

FreeRTOS

FreeRTOS内核

FreeRTOS-Plus

FreeRTOS组件,一般我们会选择使用第三方的组件

tools

工具

GitHub-FreeRTOS-Home

FreeRTOS的GitHub仓库链接

Quick_Start_Guide

快速入门指南官方文档链接

Upgrading-to-FreeRTOS-xxx

升级到指定FreeRTOS版本官方文档链接

History.txt

FreeRTOS历史更新记录

其他

其他

FreeRTOS文件夹结构

名称

描述

Demo

FreeRTOS演示例程,支持多种芯片架构、多种型号芯片

License

FreeRTOS相关许可

Source

FreeRTOS源码,最重要的文件夹

Test

公用以及移植层测试代码

Source文件夹结构如下

名称

描述

include

内包含了FreeRTOS的头文件

portable

包含FreeRTOS移植文件:与编译器相关、keil编译环境

croutine.c

协程相关文件:进程下细分线程,线程下细分协程

event_groups.c

事件相关文件

list.c

列表相关文件

queue.c

队列相关文件

stream_buffer.c

流式缓冲区相关文件

tasks.c

任务相关文件

timers.c

软件定时器相关文件

include文件夹和.c文件是通用的头文件和 C 文件,这两部分的文件适用于各种编译器和处理器,是通用的。标红的是移植必需的,其他.c文件根据需要选取。

portable文件夹里根据编译器、内核等实际环境对应选取。

portable文件夹结构

FreeRTOS操作系统归根到底是一个软件层面的东西,需要跟硬件联系在一起,portable文件夹里面的东西就是连接桥梁。由于我们使用MDK开发,因此这里只重点介绍其中的部分移植文件。

名称

描述

Keil

指向RVDS文件夹

RVDS

不同内核芯片的移植文件

MemMang

内存管理相关文件

Keil文件夹里只有一个See-also-the-RVDS-directory.txt,意思是让我们看RVDS文件夹。

RVDS文件夹

RVDS 文件夹包含了各种处理器相关的文件夹,FreeRTOS 是一个软件,单片机是一个硬件,FreeRTOS 要想运行在一个单片机上面,它们就必须关联在一起。

关联还是得通过写代码来关联,这部分关联的文件叫接口文件,通常由汇编和 C 联合编写。这些接口文件都是跟硬件密切相关的,不同的硬件接口文件是不一样的,但都大同小异。编写这些接口文件的过程我们就叫移植,移植的过程通常由 FreeRTOS 和 mcu 原厂的人来负责,移植好的这些接口文件就放在 RVDS 这个文件夹的目录下。

FreeRTOS 为我们提供了 cortex-m0、m3、m4 和 m7 等内核的单片机的接口文件,根据mcu的内核选择对应的接口文件即可。其实准确来说,不能够叫移植,应该叫使用官方的移植, 因为这些跟硬件相关的接口文件,RTOS 官方都已经写好了,我们只是使用而已。

以 ARM_CM3 这个文件夹为例,里面只有“port.c”与“portmacro.h” 两个文件,

  • port.c文件:里面的内容是由 FreeRTOS 官方的技术人员为 Cortex-M3 内核的处理器写的接口文件,里面核心的上下文切换代码是由汇编语言编写而成,对技术员的要求比较高,我们只是使用的话只需拷贝过来用即可。
  • portmacro.h文件:port.c文件对应的头文件,主要是一些数据类型和宏定义。
MemMang文件夹 

MemMang 文件夹下存放的是跟内存管理相关的,总共有五个 heap 文件以及一个 readme 说明文件。

 这五个 heap 文件在移植的时候必须使用一个,因为 FreeRTOS 在创建内核对象的时候使用的是动态分配内存,而这些动态内存分配的函数则在这几个文件里面实现,不同的分配算法会导致不同的效率与结果,后面在内存管理中我们会讲解每个文件的区别,由于现在是初学,所以我们选用 heap4.c 即可。

FreeRTOS在基于寄存器项目中移植步骤

目录添加源码文件

在例程的根路径下,新建“FreeRTOS”文件夹,并且在里面新建“portable”和“source”两个空文件夹。

拷贝FreeRTOS源码的Source文件夹的7个.c文件到例程的source文件夹。

拷贝FreeRTOS源码portable文件夹下的Keil、RVDS、MemMang到例程的portable文件夹下。

其中例程的MemMang可只保留heap_4.c:

其中例程的RVDS可只保留ARM_CM3(对应我们的芯片内核)。

拷贝FreeRTOS源码include文件夹到例程的FreeRTOS文件夹下。

FreeRTOSConfig.h 文件是 FreeRTOS 的工程配置文件,因为 FreeRTOS 是可以裁剪的 实时操作内核,应用于不同的处理器平台,用户可以通过修改这个 FreeRTOS 内核的配置头文件来裁剪 FreeRTOS 的功能,所以我们把它拷贝一份放在 user 这个文件夹下面。

工程添加源码文件

工程新建Group“FreeRTOS/Source”和“FreeRTOS/Portable”。

系统配置文件修改

FreeRTOSConfig.h中添加如下3个配置:

#define xPortPendSVHandler  PendSV_Handler
#define vPortSVCHandler     SVC_Handler
#define INCLUDE_xTaskGetSchedulerState   1

第一行:中断服务程序的名称---可挂起的系统服务---可以等当前的中断服务程序结束然后执行

第二行:中断服务程序的名称---通过SWI指令的系统服务调用---可以使用硬件资源

第三行:开关选项(include...)获取调度器的状态

main.c中添加如下代码

FreeRTOS使用滴答定时器来实现的系统时基, 需要实现滴答定时器的中断,并在中断中添加下面的代码.

extern void xPortSysTickHandler(void);
void  SysTick_Handler(void)
{if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){xPortSysTickHandler();}
}

FreeRTOS在基于HAL库项目中移植步骤

目录添加源码文件

在例程的根路径下,新建“FreeRTOS”文件夹,并且在里面新建“portable”和“source”两个空文件夹。

拷贝FreeRTOS源码的Source文件夹的7个.c文件到例程的source文件夹。

拷贝FreeRTOS源码portable文件夹下的Keil、RVDS、MemMang到例程的portable文件夹下。

其中例程的MemMang可只保留heap_4.c:

其中例程的RVDS可只保留ARM_CM3(对应我们的芯片内核)。

拷贝FreeRTOS源码include文件夹到例程的FreeRTOS文件夹下。

FreeRTOSConfig.h 文件是 FreeRTOS 的工程配置文件,因为 FreeRTOS 是可以裁剪的 实时操作内核,应用于不同的处理器平台,用户可以通过修改这个 FreeRTOS 内核的配置 头文件来裁剪 FreeRTOS 的功能,所以我们把它拷贝一份放在 user 这个文件夹下面。

在源码“..\FreeRTOS\Demo”文件夹下面找到 “ CORTEX_STM32F103_Keil ” 这个文件夹下,找到 “FreeRTOSConfig.h”文件,然后拷贝到我们工程下的 “Core/Inc” 文件夹下即可,等下我们需要对这个文件进行修改。

工程添加源码文件

工程新建Group“FreeRTOS/Source”和“FreeRTOS/Portable”。

FreeRTOS/Source添加.c文件。

FreeRTOS/Portable添加port.c和heap_4.c文件。

添加配置头文件。

添加头文件。

FreeRTOS 的源码已经添加到开发环境的组文件夹下面,编译的时候需要为这些源文件指定头文件的路径,不然编译会报错。FreeRTOS 的源码里面只有 include 和RVDS\ARM_CM3这两个文件夹下面有头文件,只需要将这两个头文件的路径在开发环境里面指定即可。

同时我们还将 FreeRTOSConfig.h 这个头文件拷贝到了工程根目录下的 Core/Inc 文件夹下,这个路径本身就在开发环境里面。(放其他路径也可以, 就是一个.h文件)

系统配置文件修改

FreeRTOSConfig.h中添加如下3个配置:

#define xPortPendSVHandler  PendSV_Handler
#define vPortSVCHandler     SVC_Handler
#define INCLUDE_xTaskGetSchedulerState   1

stm32f1xx_it.c" style="margin-left:.0001pt;text-align:justify;">修改stm32f1xx_it.c(hal库自动生成的文件)

引入头文件
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
#include "task.h"
/* USER CODE END Includes */

注释掉2个函数

// void SVC_Handler(void)
// {
// }// void PendSV_Handler(void)
// {
// }

添加SysTick时钟中断服务函数

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
extern void xPortSysTickHandler(void);
/* USER CODE END PV */void SysTick_Handler(void)
{/* USER CODE BEGIN SysTick_IRQn 0 *//* USER CODE END SysTick_IRQn 0 */HAL_IncTick();/* USER CODE BEGIN SysTick_IRQn 1 */if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {xPortSysTickHandler();}/* USER CODE END SysTick_IRQn 1 */
}

注意:HAL本身和FreeRTOS都需要依赖SysTick,可能出现。

SysTick以最低的中断优先级运行,而FreeRTOS的临界区功能需要屏蔽中断,可能导致不可预知的问题。为了保险起见,可以考虑在SYS选择时钟源的时候换成其他的。

系统配置文件说明

FreeRTOSConfig.h 配置文件作用:对FreeRTOS的功能进行配置和裁剪,以及API函数的使能等。

官网中文说明:https://www.freertos.org/zh-cn-cmn-s/a00110.html

整体的配置项可以分为三类:

  • INCLUDE开头:一般是“INCLUDE_函数名”,函数的使能,1表示可用,0表示禁用。
  • config开头:FreeRTOS的一些功能配置,比如基本配置、内存配置、钩子配置、中断配置等。
  • 其他配置:PendSV宏定义、SVC宏定义。

FreeRTOS数据类型

针对每个移植定义四种类型。即:

TickType_t

如果 configUSE_16_BIT_TICKS 设置为非零 (true) ,则将 TickType_t 定义为无符号的 16 位类型。如果 configUSE_16_BIT_TICKS 设置为零(假),则将 TickType_t 定义为无符号的 32 位类型。

这个类型的变量, 通常用来表示系统节拍计数器的值。FreeRTOS系统中,每隔一段时间会进行一次滴答定时器中断处理,这个时间间隔就是系统的节拍周期。TickType_t类型的变量记录了系统过去的节拍次数。

BaseType_t

架构中最有效、最自然的类型。例如,在 32 位架构上,BaseType_t 会被定义为 32 位类型。在 16 位架构上,BaseType_t 会被定义为 16 位类型。是有符号的。

UBaseType_t

是无符号的BaseType_t

StackType_t

意指架构用于存储堆栈项目的 类型。通常是 16 位架构上的 16 位类型和 32 位架构上的 32 位类型,但也有例外情况。供 FreeRTOS 内部使用

FreeRTOS的命名规范

了解FreeRTOS的编码规范,有助于我们理解和学习FreeRTOS的使用.

变量

  1. 变量名称使用驼峰式大小写,具有明确的描述性,并使用完整的单词(没有缩写,但普遍接受的缩写除外)。
  2. uint32_t 类型变量以 ul 为前缀,其中“u”表示“unsigned” ,“l”表示“long”。
  3. uint16_t 类型变量以 us 为前缀,其中“u”表示“unsigned” , “s”表示“short”。
  4. uint8_t 类型变量以 uc 为前缀,其中“u”表示“unsigned” , “c”表示“char ”。
  5. 非 stdint 类型的变量以 x 为前缀。例如,BaseType_t 和 TickType_t,二者分别是可移植层定义的定义类型,主要架构的自然类型或最有效类型,以及用于保存 RTOS ticks 计数的类型。
  6. 非 stdint 类型的未签名变量存在附加前缀 u。例如,UBaseType_t(无符号的BaseType_t)类型变量以 ux 为前缀。
  7. size_t 类型变量也带有 x 前缀。
  8. 枚举变量以 e 为前缀
  9. 指针以附加 p 为前缀,例如,指向 uint16_t 的指针将以 pus 为前缀。
  10. 根据 MISRA 指南,无符号 char 类型仅可包含 ASCII 字符,并以 c 为前缀。
  11. 根据 MISRA 指南,char * 类型变量仅可包含指向 ASCII 字符串的指针,并以 pc 为前缀。

函数

  1. 函数名称使用驼峰式大小写,具有明确的描述性,并使用完整的单词(无缩写,但普遍接受的缩写除外)。
  2. 文件作用域静态(私有)函数以 prv 为前缀。
  3. 根据变量定义的相关规定,API 函数以其返回类型为前缀,并为 void 添加前缀 v。
  4. API 函数名称以定义 API 函数文件的名称开头。

比如一个函数 vTaskDelay , 从函数名可以得到如下信息:v表示这个函数的返回值是void, Task表示这个函数定义在Task.c文件中, Delay表示函数的功能

  1. 宏具有明确的描述性,并使用完整的单词(无缩写,但普遍接受的缩写除外)。
  2. 宏以定义宏的文件为前缀。前缀为小写。例如,在 FreeRTOSConfig.h 中定义 configUSE_PREEMPTION。
  3. 除前缀外,所有宏均使用大写字母书写,并使用下划线来分隔单词。

http://www.ppmy.cn/devtools/150490.html

相关文章

LLM 大语言模型学习记录

文章目录 1. 写在最前面2. 让 gpt-4o-mini 解释 LLM 的原理3. 让 gpt-4o-mini 解释 LLM 的使用场景4. 让 gpt-4o-mini 解释 LLM 的局限性5. 碎碎念 1. 写在最前面 大语言模型(LLM)似乎已经成为 AI 领域的宠儿,不少公司争相推出自研的大模型。…

代码随想录day13| 二叉树理论基础| 递归遍历|迭代遍历| 统一迭代 |层序遍历

二叉树是一种每个节点最多有两个子节点的树结构,它由若干节点构成,每个节点包含数据部分和两个子节点的引用(指向左子节点和右子节点)。常见的二叉树类型包括完全二叉树、满二叉树和平衡二叉树等。 1. 二叉树的种类 二叉树有两种…

将Docker运行中的容器保存为镜像并导出导入

在 Docker 中,将运行中的容器保存为镜像并导出是一个常见的操作,特别是在你需要迁移或备份容器配置和数据时。以下是具体步骤: 1. 将运行中的容器保存为镜像 首先,你需要通过docker commit命令将运行中的容器保存为一个新的镜像。…

工程水印相机结合图纸,真实现场时间地点,如何使用水印相机,超简单方法只教一次!

在工程管理领域,精准记录现场信息至关重要。水印相机拍照功能,为工程人员提供了强大的现场信息记录工具,助力工程管理和统计工程量,更可以将图片分享到电脑、分享给同事,协同工作。 一、打开图纸 打开手机版CAD快速看图…

全网首发:编译libssh,产生类似undefined reference to `EVP_aes_256_ctr@OPENSSL_1_1_0‘的大量错误

具体错误 前面和后面的: /opt/linux/x86-arm/aarch64-mix210-linux/host_bin/../lib/gcc/aarch64-linux-gnu/7.3.0/../../../../aarch64-linux-gnu/bin/ld: warning: libcrypto.so.1.1, needed by ../lib/libssh.so.4.10.1, not found (try using -rpath or -rpat…

4. scala高阶之隐式转换与泛型

背景 上一节,我介绍了scala中的面向对象相关概念,还有一个特色功能:模式匹配。本文,我会介绍另外一个特别强大的功能隐式转换,并在最后介绍scala中泛型的使用 1. 隐式转换 Scala提供的隐式转换和隐式参数功能&#…

Python 替换excel 单元格内容

要在Python中替换Excel单元格的内容,你可以使用openpyxl库。openpyxl是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的库。 安装openpyxl 首先,你需要安装openpyxl库。如果还没有安装,可以使用pip进行安装: pip install ope…

css 布局及动画应用(flex+transform+transition+animation)

文章目录 css 布局及动画应用animationtransform,transition,animation 综合应用实例代码实例解释 css 布局及动画应用 Display用法 作用:用于控制元素的显示类型,如块级元素、内联元素、无显示等。常见属性值及示例:…