当前位置: 首页 > article >正文

STM32 FreeRTOS移植

目录

FreeRTOS源码结构介绍

获取源码

1、 官网下载

2、 Github下载

源码结构介绍

源码整体结构

FreeRTOS文件夹结构

Source文件夹结构如下

portable文件夹结构

RVDS文件夹

MemMang文件夹 

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

目录添加源码文件

工程添加源码文件

系统配置文件修改

main.c中添加如下代码

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

目录添加源码文件

工程添加源码文件

系统配置文件修改

修改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(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.kler.cn/a/503415.html

相关文章:

  • Elasticsearch ES|QL 地理空间索引加入纽约犯罪地图
  • Vue Diff 算法完全解析
  • ImportError: attempted relative import with no known parent package 报错的解决!
  • WINFORM - DevExpress -> DevExpress总结[安装、案例]
  • 图解Git——分支的新建与合并《Pro Git》
  • Python脚本自动发送电子邮件
  • 《Java核心技术II》并行流
  • Centos 宝塔安装
  • system generator 使用高版本的matlab
  • 【大数据】机器学习------神经网络模型
  • Go oom分析(一)——使用pprof线上分析
  • element ui前端小数计算精度丢失的问题如何解决?
  • 计算机视觉与深度学习 | 使用深度学习来训练基于视觉的车辆检测器(matlab源码-faster RCNN)
  • 算法-贪心算法简单介绍
  • 设计一个流程来生成测试模型安全性的问题以及验证模型是否安全
  • 【Uniapp-Vue3】onUnload页面卸载和onPageScroll页面监听滚动
  • PySpark用sort-merge join解决数据倾斜的完整案例
  • B3DM转换成FBX
  • Pgsql存储占用分析
  • AR 在高校实验室安全教育中的应用
  • 基于PHP的校园兼职系统设计和开发
  • 【Vue】Vue组件--上
  • [读书日志]从零开始学习Chisel 第十三篇:Scala的隐式参数与隐式转换(敏捷硬件开发语言Chisel与数字系统设计)
  • OLED显示字符
  • 八 rk3568 android11 AP6256 蓝牙调试
  • 网络安全之sql注入