之前讲过FreeRTOS,参看:FreeRTOS学习 – 再识
讲解了什么是FreeRTOS、FreeRTOS的特点、源码下载和目录文件介绍。
这里就不做更多讲解了,直接介绍怎么移植。
一、下载
官网:
https://www.freertos.org/zh-cn-cmn-s/
源码下载:
二、移植
在上篇文章GD32F4开发 – 工程模板创建 创建的工程里,新建一个FreeRTOS文件夹。
将源码FreeRTOSv202212.01\FreeRTOS\Source\include文件夹,移植到新建工程的FreeRTOS文件夹下。
将源码FreeRTOSv202212.01\FreeRTOS\Source\portable文件夹,移植到新建工程的FreeRTOS文件夹下。只保留Keil、MemMang、RVDS,将其他删除。
将源码FreeRTOSv202212.01\FreeRTOS\Source文件夹,移植到新建工程的FreeRTOS文件夹下。只保留C文件。
将FreeRTOSv202212.01\FreeRTOS\Demo\CORTEX_STM32F103_Keil文件夹下的FreeRTOSConfig.h,移植到新建工程的FreeRTOS\include文件夹下
至此,文件移植完成。
三、文件描述
源文件里的Source目录文件描述:
其中:portable这个文件夹
Keil文件夹
:里面的东西是必须的,但是我们打开keil文件夹以后里面只有一个文件:See-also-the-AVDS-directory.txt,意思是参考RVDS文件夹里面的东西!
MemMang
: 这个文件夹就是跟内存管理相关的,我们移植的时候是必须的。
RVDS
文件夹针对不同的架构的MCU 做了详细的分类,GD32F407 就参考 ARM_CM4F,打开 ARM_CM4F 文件夹。
ARM_CM4F 有两个文件,这两个文件就是我们移植的时候所需要的!
四、创建FreeRTOS分组
创建FreeRTOS_core,添加FreeRTOS\Source目录下的C文件。
创建FreeRTOS_portable,添加FreeRTOS\portable\MemMang
文件夹下的heap_4.c
和FreeRTOS\portable\RVDS\ARM_CM4F
文件夹下的port.c
。
.
这里为什么选择heap_4.c 和 ARM_CM4F文件夹下的port.c?
在使用RVDS(RealView Development Suite,即Arm的RealView开发工具)与FreeRTOS进行GD32F407项目的开发时,选择合适的移植文件对系统性能优化和浮点运算支持非常重要。### GD32F407的合适选择
使用ARM_CM4F移植文件夹:
GD32F407基于ARM Cortex-M4内核,并支持硬件浮点运算单元(FPU),因此选择`ARM_CM4F`目录中的移植文件是合适的。
RVDS编译器设置:
在RVDS中配置项目,确保启用FPU支持,这样编译器可以利用硬件浮点单元进行优化。
设置优化选项以从硬件特性中获得最佳性能。
移植文件中的端口设置:
确保FreeRTOSConfig.h中具有对应的设置,以充分利用GD32F407和FPU功能,例如:
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configUSE_FLOATING_POINT 1
#define configMINIMAL_STACK_SIZE ((unsigned short)256)### 总结
对于GD32F407上的FreeRTOS开发,推荐使用`ARM_CM4F`作为移植层,而在RVDS中进行编译时,确保启用了FPU支持,以便运行时利用硬件浮点特性进行优化。这样可以最大化利用GD32F407的计算能力和实时性能。
常用的heap_x.c选项
heap_1.c:
特点:最简单的内存管理,支持分配但不支持释放。
适用场景:适用于内存一直增长且没有释放需求的简单应用。
heap_2.c:
特点:支持内存分配和简单释放,但不支持合并空闲内存块。
适用场景:适用于内存分配和释放较少,且对碎片化不敏感的应用。
heap_3.c:
特点:使用C库的`malloc`和`free`,依赖于系统库的实现。
适用场景:适用于希望利用标准库内存管理的环境,多用于测试或特殊应用。
heap_4.c:
特点:支持合并空闲内存块,提供最好的碎片管理。
适用场景:适用于内存频繁分配和释放,并且对碎片化敏感的应用。
heap_5.c:
特点:添加对多个内存区域的支持,适合复杂的内存布局。
适用场景:适用于多个不连续内存区域的高级内存管理需求。
### 为GD32F407的推荐选择
heap_4.c:通常推荐使用`heap_4.c`,它在多个内存块的合并和碎片管理方面表现最佳。这对于GD32F407这样有足够RAM空间的M4系列处理器特别合适,尤其是在内存使用相对复杂的应用环境中。
选择合适的heap实现能有效提高系统内存管理的效率和稳定性。如果你的系统内存使用模式特别复杂,可以考虑`heap_5.c`来管理多个内存区域。
工程目录如下:
五、添加相关的头文件路径
六、FreeRTOSConfig.h配置
参看:FreeRTOS学习 – FreeRTOSConfig.h介绍
七、编译
编译一下,没有报错。说明移植完成了。
八、测试
创建一个task进行测试。
修改main.c
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"#include "FreeRTOS.h"
#include "task.h"//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_STK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define FLOAT_TASK_PRIO 3
//任务堆栈大小
#define FLOAT_STK_SIZE 128
//任务句柄
TaskHandle_t FLOATTask_Handler;
//任务函数
void float_task(void *pvParameters);//开始任务任务函数
void start_task(void *pvParameters)
{taskENTER_CRITICAL(); //进入临界区//创建float任务xTaskCreate((TaskFunction_t )float_task, (const char* )"float_task", (uint16_t )FLOAT_STK_SIZE, (void* )NULL, (UBaseType_t )FLOAT_TASK_PRIO, (TaskHandle_t* )&FLOATTask_Handler); vTaskDelete(StartTask_Handler); //删除开始任务taskEXIT_CRITICAL(); //退出临界区}//float任务函数
void float_task(void *pvParameters)
{static float float_num = 0.00;while(1){float_num+=0.01f;printf("float_num的值为:%.4f\r\n",float_num);vTaskDelay(1000);}
}/*!\brief main function\param[in] none\param[out] none\retval none
*/
int main(void)
{//创建开始任务xTaskCreate((TaskFunction_t )start_task, //任务函数(const char* )"start_task", //任务名称(uint16_t )START_STK_SIZE, //任务堆栈大小(void* )NULL, //传递给任务函数的参数(UBaseType_t )START_TASK_PRIO, //任务优先级(TaskHandle_t* )&StartTask_Handler); //任务句柄 vTaskStartScheduler(); //开启任务调度// systick_config();// while(1) {
// }
}
示例工程:
链接:GD32F407_OS_Temp_20240913.rar
提取码:djse