FreeRTOS开发一、FreeRTOS移植

1、FreeRTOS 源码下载

两个下载链接, 一个是官网:http://www.freertos.org/, 另外一个是代码托管网站:https://sourceforge.net/projects/freertos/files/FreeRTOS/
打开代码托管网站链接,我们选择FreeRTOS 的版本 V9.0.0(2016 年),尽管现在 FreeRTOS 的版本已经更新到V10.4.1 了,但是我们还是选择V9.0.0,因为内核很稳定,并且网上资料很多,因为 V10.0.0 版本之后是亚马逊收购了 FreeRTOS 之后才出来的版本,主要添加了一些云端组件,我们所讲的 FreeRTOS 是实时内核,采用 V9.0.0 版本足以。
在这里插入图片描述在这里插入图片描述
点击后就会自动下载,然后解压zip压缩包以后:
在这里插入图片描述

2、FreeRTOS 文件介绍

FreeRTOS 包含 Demo 例程和内核源码,如下图所示:
在这里插入图片描述
Source 文件夹:里面包含的是 FreeRTOS 内核的源代码,我们移植 FreeRTOS的时候就需要这部分源代码。
Demo 文件夹:里面包含了 FreeRTOS 官方为各个单片机移植好的工程代码,FreeRTOS 为了推广自己,会给各种半导体厂商的评估板写好完整的工程程序,这些程序就放在 Demo 这个目录下,这部分 Demo 非常有参考价值。我们把FreeRTOS 到 STM32 的时候,FreeRTOSConfig.h 这个头文件就是从这里拷贝过来的,下面我们对 FreeRTOS 的文件夹进行分析说明。
License 文件夹:这个文件夹里面就是相关的许可信息,要用 FreeRTOS 做产品的得仔细看看,尤其是要出口的产品。

2.1、Source 文件夹

打开“FreeRTOS/Source”文件夹,其内文件及文件夹如下所示:
在这里插入图片描述
编号①和③包含的是 FreeRTOS 的通用的头文件和 C 文件,这两部分的文件适用于各种编译器和处理器,是通用的。需要移植的头文件和 C 文件放在编号②portblle 这个文件夹。
我们打开 portblle 这个文件夹,可以看到里面很多与编译器相关的文件
夹,在不同的编译器中使用不同的支持文件,如下所示:
在这里插入图片描述
编号①中的 KEIL 就是我们就是我们使用的编译器,打开 KEIL 文件夹的时候,你会看到一句话“See-also-the-RVDS-directory.txt”,其实 KEIL 里面的内容跟 RVDS 里面的内容一样,所以,我们只需要编号③RVDS 文件夹里面的内容即可。而编号②MemMang 文件夹下存放的是跟内存管理相关的,稍后具体介绍。

(1)RVDS 文件夹

打开 RVDS 文件夹,下面包含了各种处理器相关的文件夹,从文件夹的名字我们就非常熟悉了,我们学习的 STM32 有 M0、M3、M4 等各种系列,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 文件对应的头文件,主要是一些数据类型和宏定义。文件如下:
在这里插入图片描述

(2)MemMang 文件夹

编号②MemMang 文件夹下存放的是跟内存管理相关的,总共有五个heap 文件以及一个 readme 说明文件,这五个 heap 文件在移植的时候必须使用一个,因为 FreeRTOS 在创建内核对象的时候使用的是动态分配内存,而这些动态内存分配的函数则在这几个文件里面实现,不同的分配算法会导致不同的效率与结果,后面在内存管理中我们会讲解每个文件的区别,由于现在是初学,所以我们选用 heap4.c 即可。如下图所示:
在这里插入图片描述
至此,FreeRTOS/source 文件夹下的主要内容就讲完,剩下的可根据兴趣自行查阅。

2.2、Demo 文件夹

这个目录下内容就是 Deme 例程,我们可以直接打开里面的工程文件,各种开发平台的完整 Demo,开发者可以方便的以此搭建出自己的项目,甚至直接使用。FreeRTOS 当然也为 ST 写了很多 Demo,其中就有F1、F4、F7 等工程,这对我们学习 FreeRTOS 是非常方便的,当遇到不懂的直接就可以参考官方的Demo。如下所示:
在这里插入图片描述

2.3、FreeRTOS-Plus 文件夹

FreeRTOS-Plus 文件夹里面包含的是第三方的产品,一般我们不需要使用,FreeRTOS-Plus 的预配置演示项目组件(组件大多数都要收费),大多数演示项目都是在 Windows 环境中运行的,使用 FreeRTOS windows 模拟器,所以暂时不需要关注这个文件夹。

2.4、HTML 文件

一些直接可以打开的网页文件,里面包含一些关于 FreeRTOS 的介绍,是FreeRTOS 官方人员所写,所以都是英文的,有兴趣可以打开看看,具体相关内容可以看 HTML 文件名称。

3、FreeRTOS 移植

要将 FreeRTOS 移植到 STM32 上,需要一个基础工程,可直接使用一个之前做好的工程(使用库函数编写的LED灯闪烁的例子),为了不破坏基础工程的完整性,我们重新复制一份,并重命名为“FreeRTOS移植模板_LED闪烁”。
如下:
在这里插入图片描述

3.1、添加 FreeRTOS 源码

在前面创建的好的基础工程“FreeRTOS移植模板_LED闪烁”内新建一个“FreeRTOS”文件夹用于保存 FreeRTOS 移植所需源码。如下所示:
在这里插入图片描述
创建好 FreeRTOS 文件夹后,就可以将 FreeRTOS 源码添加到该文件中,前面我们已经讲解了 FreeRTOS 源码文件内容,可直接将源码“FreeRTOSv9.0.0\FreeRTOS\Source”内容全部拷贝到新建的“FreeRTOS”文件夹中,如下所示:
在这里插入图片描述粘贴到工程文件夹下的FreeRTOS文件夹中
在这里插入图片描述前面详细的讲解过 portable 文件夹,对于使用 KEIL 环境我们只需要留下keil、MemMang 和 RVDS 这三个文件夹,其他的都可以删除掉(如果使用其他编译环境,根据实际情况选择)。
如下所示:
在这里插入图片描述

3.2、向工程组添加文件

打开基础工程,新建分组 FreeRTOS_core 和 FreeRTOS_port,然后向这两个分组中添加FreeRTOS 源码文件。FreeRTOS_core 组所添加的文件位置在“\FreeRTOS移植模板_LED闪烁\FreeRTOS”下源文件,FreeRTOS_port 组所添加的文件位置在“\FreeRTOS移植模板_LED闪烁\FreeRTOS\portable\RVDS\ARM_CM3”和“\FreeRTOS移植模板_LED闪烁\FreeRTOS\portable\MemMang”下源文件。如下图所示:
在这里插入图片描述分组 FreeRTOS_core 中的文件在什么地方就不说了,打开 FreeRTOS 源码一目了然。重点来说说 FreeRTOS_port 分组中的 port.c 和 heap_4.c 是怎么来的,port.c 是 RVDS 文件夹下的 ARM_CM3 中的文件,因为 STM32F103 是Cortex-M3 内核的,因此要选择 ARM_CM3 中的 port.c 文件。假如使用的是其它内核芯片,则选择对应内核文件夹内的 port.c 文件。heap_4.c 是 MemMang 文件夹中的,前面说了 MemMang 是跟内存管理相关的,里面有 5 个 c 文件:heap_1.c、heap_2.c、heap_3.c、heap_4.c 和 heap_5.c。这 5 个 c 文件是五种不同的内存管理方法。这 5 个文件都可以用来作为 FreeRTOS 的内存管理文件,只是它们的实现原理不同,各有利弊。这里我们选择heap_4.c,至于原因,后面会有一章节专门来讲解 FreeRTOS 的内存管理,到时候大家就知道原因了。这里就先选择 heap_4.c,毕竟本章的重点是 FreeRTOS 的移植。

3.3、添加头文件路径

添加完 FreeRTOS 源码中的 C 文件以后还要添加 FreeRTOS 源码的头文件路径,头文件路径如下图所示:
在这里插入图片描述
头文件路径添加完成以后编译一下,看看有没有什么错误,结果会发现提示打不开“FreeRTOSConfig.h”这个文件,如下图所示:
在这里插入图片描述这是因为缺少 FreeRTOSConfig.h 文件,这个文件在哪里找呢?你可以自己创建,显然这不是一个明智的做法。我们可以找找 FreeRTOS 的官方移植工程中会不会有这个文件,打开前面下载好的 FreeRTOS 源码文件,里面有各种芯片移植好的 Demo,针对 STM32F103 的移植工程文件,文件夹是CORTEX_STM32F103_Keil,如果使用的是其它内核芯片,请打开对应的工程。打开以后如下图所示:
在这里插入图片描述为了方便管理,我们将该文件复制一份存放到“FreeRTOS移植模板_LED闪烁\FreeRTOS\include”位置下,如下图所示:
在这里插入图片描述我们再编译一下工程,没有错误,如下图所示:
在这里插入图片描述FreeRTOSConfig.h 是何方神圣?看名字就知道,他是 FreeRTOS 的配置文件,一般的操作系统都有裁剪、配置功能,而这些裁剪及配置都是通过一个文件来完成的,基本都是通过宏定义来完成对系统的配置和裁剪的。

3.4、修改 FreeRTOSConfig.h 文件

FreeRTOSConfig.h 是直接从 demo 文件夹下面拷贝过来的,该头文件对裁剪整个 FreeRTOS 所需的功能的宏均做了定义,有些宏定义被使能,有些宏定义被失能,一开始我们只需要配置最简单的功能即可。要想随心所欲的配置FreeRTOS 的功能,我们必须对这些宏定义的功能有所掌握,下面我们先简单的介绍下这些宏定义的含义,然后再对这些宏定义进行修改。

3.5、修改 stm32f10x_it.c 文件

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()这两个函数了,具体修改代码如下:
1、添加头文件

#include "FreeRTOS.h" //FreeRTOS 使用
#include "task.h"

2、注释掉PendSV_Handler和SVC_Handler
在这里插入图片描述在这里插入图片描述3、修改SysTick_Handler部分

extern void xPortSysTickHandler(void);
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行{xPortSysTickHandler();}
}

在这里插入图片描述

3.6、修改 Delay.c 和 Delay.h 文件,设置系统时钟频率,开启SYSTICK和开启SYSTICK中断

首先在 Delay.c 文件开头添加 FreeRTOS 头文件,如下:
Delay.c

#include "FreeRTOS.h" //FreeRTOS 使用
#include "task.h"
#include "stm32f10x.h"static u8  fac_us=0;							//us延时倍乘数			   
static u16 fac_ms=0;							//ms延时倍乘数//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟,基础例程里面SYSTICK时钟频率为AHB/8
//SYSCLK:系统时钟频率
void SysTick_Init(u8 SYSCLK)
{u32 reload;SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟  HCLKfac_us=SystemCoreClock/1000000;				//不论是否使用OS,fac_us都需要使用reload=SystemCoreClock/1000000;				//每秒钟的计数次数 单位为M  reload*=1000000/configTICK_RATE_HZ;			//根据configTICK_RATE_HZ设定溢出时间//reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右	fac_ms=1000/configTICK_RATE_HZ;				//代表OS可以延时的最少单位	   SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;   	//开启SYSTICK中断SysTick->LOAD=reload; 						//每1/configTICK_RATE_HZ秒中断一次	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;   	//开启SYSTICK				   
}								    //延时nus
//nus:要延时的us数.	
//nus:0~204522252(最大值即2^32/fac_us@fac_us=168)	    								   
void Delay_us(u32 nus)
{		u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD;				//LOAD的值	    	 ticks=nus*fac_us; 						//需要的节拍数 told=SysTick->VAL;        				//刚进入时的计数器值while(1){tnow=SysTick->VAL;	if(tnow!=told){	    if(tnow<told)tcnt+=told-tnow;	//这里注意一下SYSTICK是一个递减的计数器就可以了.else tcnt+=reload-tnow+told;	    told=tnow;if(tcnt>=ticks)break;			//时间超过/等于要延迟的时间,则退出.}  };										    
}  
//延时nms
//nms:要延时的ms数
//nms:0~65535
void Delay_ms(u32 nms)
{	if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行{		if(nms>=fac_ms)						//延时的时间大于OS的最少时间周期 { vTaskDelay(nms/fac_ms);	 		//FreeRTOS延时}nms%=fac_ms;						//OS已经无法提供这么小的延时了,采用普通方式延时    }delay_us((u32)(nms*1000));				//普通方式延时
}//延时nms,不会引起任务调度
//nms:要延时的ms数
void Delay_xms(u32 nms)
{u32 i;for(i=0;i<nms;i++) delay_us(1000);
}/*** @brief  秒级延时* @param  xs 延时时长,范围:0~4294967295* @retval 无*/
void Delay_s(u32 xs)
{while(xs--){Delay_ms(1000);}
} 

Delay.h

#ifndef __DELAY_H
#define __DELAY_Hvoid Delay_us(u32 us);
void Delay_ms(u32 ms);
void Delay_xms(u32 nms);
void Delay_s(u32 s);#endif

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

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

相关文章

全域运营平台是什么?优缺点有哪些?

当下&#xff0c;全域运营赛道逐渐兴盛&#xff0c;全域运营服务商的数量也开始呈现爆发趋势。在此背景下&#xff0c;很多人都对某些品牌的全域运营平台优缺点产生了浓厚的兴趣。由于小编只使用过微火全域运营平台&#xff0c;因此&#xff0c;本期会着重分析微火运营平台的优…

【软考】设计模式之桥接模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 适用性6. 优点7. 缺点8. java示例 1. 说明 1.将抽象部分与其实现部分分离&#xff0c;使它们都可以独立地变化。2.桥接模式&#xff08;Bridge Pattern&#xff09;属于对象结构型模式&#xff0c;又称为柄体&#xff08;Handle an…

Leetcode2105. 给植物浇水 II

Every day a Leetcode 题目来源&#xff1a;2105. 给植物浇水 II 解法1&#xff1a;双指针 设 Alice 当前下标为 i&#xff0c;初始化为 0&#xff0c;水量为 a&#xff0c;初始化为 capacityA&#xff1b;Bob 当前下标为 j&#xff0c;初始化为 n-1&#xff0c;水量为 b&am…

力扣98.验证二叉搜索树

法一&#xff08;自己思路&#xff0c;复杂了&#xff09;&#xff1a; from collections import dequeclass Solution(object):def isValidBST(self, root):""":type root: TreeNode:rtype: bool"""queue deque()if root.left!None:queue.app…

FOSS全闪对象存储--与AI/ML相向而行

行业解读需求剖析 目前&#xff0c;随着AI/ML技术得到了快速的发展及应用&#xff0c;AI/ML系统对底层高速数据访问的需求也日趋强烈&#xff0c;虽然当前业界有多种解决方案&#xff0c;但都存在一些成本或性能方面的挑战&#xff0c;就目前常用的文件存储系统来说&#xff0…

win10共享文件夹到ubuntu22

win10共享文件夹 新建用户 新建用户、设置密码。避免共享给EveryOne&#xff0c;导致隐私问题。 点击左下角的开始菜单&#xff0c;选择“设置”&#xff08;WinI&#xff09;打开设置窗口。在设置窗口中&#xff0c;搜索或直接点击“账户”进入账户设置。在账户设置中&…

机器学习中常用的几种距离——欧式、余弦等

目录 一、欧式距离&#xff08;L2距离&#xff09;二、曼哈顿距离&#xff08;L1距离&#xff09;三、汉明距离四、余弦相似度 一、欧式距离&#xff08;L2距离&#xff09; &#xff08;1&#xff09;二维空间的距离公式&#xff08;三维空间的在这个基础上类推&#xff09;&…

Windows本地部署直播录屏利器Bililive-go并实现远程添加直播间录屏

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 1. Bililive-go与套件下载1.1 获取ffmpeg1.2 获取Bililive-go1.3 配置套件 2. 本地运行测试3. 录屏…

基于单片机的光照检测系统—光敏电阻

基于单片机的光照检测系统 &#xff08;仿真&#xff0b;程序&#xff0b;原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.光敏电阻实时采集环境光照值&#xff1b; 2.采用ADC0804将模拟值转换为数字量&#xff1b; 3.四位数码管显示当前的光照…

Java JDK下载安装教程(2024年)

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

金士顿硬盘误删数据不用慌,这些恢复方法帮你忙

在数字化日益盛行的今天&#xff0c;硬盘作为存储数据的重要设备&#xff0c;其安全性与稳定性显得尤为关键。然而&#xff0c;即便是品质卓越的金士顿硬盘&#xff0c;也难免会遇到误删除数据的尴尬情况。面对这种情况&#xff0c;许多用户往往感到手足无措&#xff0c;甚至产…

LLM Agent智能体综述(万字长文)

前言 &#x1f3c6;&#x1f3c6;&#x1f3c6;在上一篇文章中&#xff0c;我们介绍了如何部署MetaGPT到本地&#xff0c;获取OpenAI API Key并配置其开发环境&#xff0c;并通过一个开发小组的多Agent案例感受了智能体的强大&#xff0c;在本文中&#xff0c;我们将对AI Agent…

Franz Electron + React 源码启动运行填坑指南

环境要求 安装miniconda python 环境electron/rebuild用得着&#xff0c;miniconda 默认自带的 python 是 3.11 版本&#xff0c;比较新&#xff1b; 安装virsual studio 2019 要把C桌面相关的都安装了&#xff0c;大概需要20G&#xff0c;不要安装到 C 盘&#xff0c;都安装到…

FlyFlow:支持驳回后自动跨节点跳回

本周更新 新增&#xff1a;审批节点驳回&#xff08;拒绝配置的驳回&#xff09;支持自动跳回当前节点新增&#xff1a;修改数据节点新增&#xff1a;删除数据节点新增&#xff1a;子流程支持配置自动跳过发起人节点优化&#xff1a;两个项目合并一个单体项目优化&#xff1a;…

JavaEE初阶-多线程进阶2

文章目录 前言一、CAS1.1 CAS的概念1.2 原子类1.3 CAS的ABA问题 二、JUC中常用类2.1 Callable接口2.2 ReentrantLock&#xff08;可重入&#xff09;2.3 Semaphore信号量2.4 CountDownLatch类2.5 CopyOnWriteArrayList类2.6 ConcurrentHashMap 前言 对于多线程进阶的部分&…

linux安装Openresty

安装必要的依赖库 指定仓库地址 下载openresty 添加环境变量 vi /etc/profile i export NGINX_HOME/usr/local/openresty/nginx/ export PATH${NGINX_HOME}/sbin:$PATH esc :wq source /etc/profile #启动 nginx # 重启 nginx -s reload #关闭 nginx -s stop

【class8】人工智能初步(图像识别-----卷积神经网络)

上节回顾 上节课&#xff0c;我们简单了解了图像识别和深度学习的相关知识。 快速回顾一下吧&#xff5e; A图像识别是以图像的主要特征为基础的。B. 图像分辨率决定图像的质量。 C&#xff0e; 像素是图像中的最小单位D. 在图像识别的原理上&#xff0c;计算机和人类在本质…

Linux 生态与工具

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 目录 Linux生态简介:Linux工具lrzsz&#xff…

Nginx配置到系统中

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Nginx(“engine x”…

Mixtral

文章目录 一、关于 MixtralMistral AI、 La PlateformeMistral AI LLMs 二、Mistral AI API账户设置 三、Mixtral 说明通过稀疏架构推动开放模型的前沿表现Instructed 模型使用开源部署堆栈部署 Mixtral在我们的平台上使用 Mixtral。 一、关于 Mixtral 官网&#xff1a;https:…