1.移植FreeRTOS
1.1 移植前准备
1.1.1基础工程
我们首先需要一个STM32裸机工程,我用的开发板是野火提供的开发板STM32F429开发板,选择的例程由野火提供的例程11-GPIO输出-使用固件库点亮LED灯,后续需要其他模块,可自行添加。
1.1.2 下载FreeRTOS
关于如何获取FreeRTOS的源码包,我们可以通过官网下载,也可以通过github网站下载,两种方式均可,这里提供官网下载方式,也提供了FreeRTOS源码包 密码。
打开FreeRTOS官网链接,点击下载FreeRTOS
选择FreeRTOS202212.01 进行下载
打开FreeRTOS\Source文件,里面的内容就是我们要移植到裸机工程里的FreeRTOS源代码
1.2 开始移植
1.2.1添加FreeRTOS内核文件
在工程模板下新建一个FreeRTOS文件夹,FreeRTOS文件夹里新建include、portable、src三个文件夹,用来存放相关头文件,portable用于保存内存管理以及处理器架构相关代码,src文件夹用于保存FreeRTOS中的核心源文件
FreeRTOS
| _ _ include
| _ _ portable
| _ _ src
1.打开FreeRTOS\Source\include文件夹,将里面所有文件拷贝到include文件夹下面
2.打开FreeRTOS\Source 将里面的.c文件全部拷贝到src文件夹下
3.这里我们使用的是开发板芯片是STM32F429,内核是Cortex-M4F,打开FreeRTOS\Source\portable
将RVDS文件拷贝到portable文件夹下,或者也可以仅拷贝RVDS里面的ARM_CM4F文件夹
4.最后我们把包含在FreeRTOS内存分配实现拷贝到工程里,FreeRTOS与其他OS的区别之一就是在与FreeRTOS操作系统在源代码中,系统初始化工程任务创建已经自动分配好内存,不需要人为分配内存。将FreeRTOS\Source\portable中MemMang拷贝到portable文件夹下,
下面是五种内存分配的区别 :
- heap_1 – 最简单,不允许释放内存
- heap_2 – 允许释放内存,但不会合并相邻的空闲块
- heap_3 – 简单包装了标准malloc()和free(),以保证线程安全
- heap_4 – 合并相邻的空闲块以避免碎片化。包含绝对地址放置选项
- heap_5 – 如同heap_4,能够跨越多个不相邻的堆。
注意:
- heap_1 不太有用,因为 FreeRTOS 添加了静态分配支持。
- heap_2 现在被视为旧版,因为较新的 heap_4 实现是首选。
1.2.2 添加FreeRTOSConfig.h配置文件到user
FreeRTOSConfig.h 文件是 FreeRTOS 的工程配置文件,因为 FreeRTOS 是可以裁剪的
实时操作内核,应用于不同的处理器平台,用户可以通过修改这个 FreeRTOS 内核的配置
头文件来裁剪 FreeRTOS 的功能,所以我们把它拷贝一份放在 user 这个文件夹下面。
打开FreeRTOSv202212.01\FreeRTOS\Demo\CORTEX_M4F_STM32F407ZG-SK目录,找到FreeRTOSConfig.h,将其拷贝到工程的user文件夹下面
1.2.3 添加FreeRTOS源码到keil工程组
1.2.3.1 新建 FreeRTOS/src 和 FreeRTOS/port 组
这里我们用到开发环境是keil,打开keil工程,新建 FreeRTOS/src 和 FreeRTOS/port 两个组文件夹,其中FreeRTOS/src 用于存放 src 文件夹的内容, FreeRTOS/port 用于存放 port\MemMang 文件夹,在 user 分组中添加我们 FreeRTOS 的配置文件FreeRTOSConfig.h至此我们的FreeRTOS 添加到工程中就已经完成,完成的效果具体见下图。
1.2.3.2 指定 FreeRTOS 头文件的路径
FreeRTOS 的源码已经添加到开发环境的组文件夹下面,编译的时候需要为这些源文件
指定头文件的路径,不然编译会报错。 FreeRTOS 的源码里面只有 FreeRTOS\include 和
FreeRTOS\port\RVDS\ARM_CM?这两个文件夹下面有头文件,只需要将这两个头文件的
路径在开发环境里面指定即可。同时我们还将 FreeRTOSConfig.h 这个头文件拷贝到了工程
根目录下的 user 文件夹下,所以 user 的路径也要加到开发环境里面。 FreeRTOS 头文件的
路径添加完成后的效果具体见下图
1.2.3.3 使能硬件浮点支持
这里我们已经将这个FreeRTOS源码,整个工程移植到裸机工程了,编译这个工程会可能会报以下错误,如下图所示
这是因为我们没有使能硬件浮点,解决方法如下:打开魔术棒,在Floating Point Hardware一栏中从之前的Not Used 切换到Single Precision,点击OK 保存配置。
再次重新编译,发现还是有错误,提示有SVC_Handler、PendSV_Handler、SysTick_Handler三个中断服务函数多次定义,如下图所示
1.2.3.4 中断服务函数多次实现
通过全局搜索查找SVC_Handler,我们发现在FreeRTOS源代码中已经实现了SVC_Handler函数,而之前在stm32f4xx_it.c文件中也实现了该函数,我们需要删除掉stm32f4xx_it.c中SVC_Handler中断服务函数的实现,其他两个也是这种情况。
1.2.3.4 禁用钩子函数
在stm32f4xx_it.c找到函数实现,并删除掉,再次编译出现一些钩子函数没有定义
搜索发现这些函数没有定义或者注释掉了,这里我们在FreeRTOSConfig.h把相关设置调成0,不使用钩子函数
再次编译, 0 Error,0 Warning,移植完毕
2.验证移植
2.1main.c添加头文件
#include "stm32f4xx.h"
#include "./led/bsp_led.h"
#include "FreeRTOS.h"
#include "task.h"
2.2 实现LED_Task()
void LED_Task()
{
while(1)
{
LED1( ON );
vTaskDelay(1000);
LED1( OFF );
vTaskDelay(1000);
}
}
2.3 在main函数里创建任务并执行调度器
int main(void)
{
TaskHandle_t LED_TaskHandle = NULL;
BaseType_t xReturn = pdPASS;
/* LED 端口初始化 */
LED_GPIO_Config();
//create led task
xReturn = xTaskCreate( LED_Task,
"LED_Task",
128,
NULL,
4,
&LED_TaskHandle);
if(xReturn == pdPASS)
{
vTaskStartScheduler();
}
}
2.4下载程序
将程序编译后,无错误提示,把程序下载到开发板,发现LED灯每隔一秒进行闪烁,说明FreeRTOS移植成功,可以正常创建任务并执行。
3.相关文件链接
FreRTOSv202212.01版本:链接:https://pan.baidu.com/s/1s9xnEuGwRhlcnHhaZzOaew 提取码:4xrd
工程源码链接 :https://pan.baidu.com/s/1P3bXQGDlBe1uPIAO9Oxjnw 提取码:frf3