前言
- 芯片:GD32F450ZGT6
- 编译环境:keil5
- STM32或者其他芯片步骤基本一样。
- 其他编译器,只是添加文件和头文件路径等操作有些许区别,freertos内容一致。
前半部分只讲如何移植,帮助大家快速移植freertos。具体讲解放在后问,有兴趣可以了解。
freertos源码下载
官网链接:FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions官网如果下载慢的话,可以从我上传的资源下载。
freertos开源,只要不用于商业场景,可以免费使用。
基础工程准备
准备自己所使用芯片的基础工程,配置好时钟即可,也可以有串口、按键等等,总之越简单越好。
我使用立创eda的梁山派开发板作为例子,所以使用了它的工程,包括时钟、串口等。
freertos移植
源码移植与裁剪
- 在工程内新建文件夹 freertos
- 将前文下载的freertos源码复制到新建的文件夹内,路径与复制内容如下图
- 裁剪源码,打开portable文件夹,只保留下图选中的MemMang和RVDS,其他文件全删除。使用IAR和GCC的,分别保留IAR和GCC文件夹,Keil文件夹打开后会发现指向了RCDS。我使用Keil,所以保留RVDS。
- MemMang中删除除了heap_4.c的全部文件
- RVDS中选择自己的芯片内核文件,我用的M4的芯片,所以删除除了ARM_CM4F之外的全部文件
- 打开工程,选择添加组,添加文件夹freertos
- 慢双击文件夹 可以修改目录中文件夹的名字
- 将裁剪后的freertos源码添加到工程
- MemMang与RVDS进去文件夹内,将heap_4.c和port.c一起添加进来,如下图
- 添加头文件路径,依次4部,选择freertos内的include文件夹和ARM_CM4F文件夹
- 添加配置文件,去下载好的freertos的源码的demo文件内,选择与自己芯片使用相同内核的Demo,我使用的M4的内核,选择了如下图选择的Demo
- 复制它们的FreeRTOSConfig.h 到我们工程的freertos-include内
- 到此,源码的移植与裁剪结束,之后在工程内完成配置,解决报错,即可使用。
freertos配置
- 编译工程,报错:..\freertos\portable\RVDS\ARM_CM4F\port.c(734): error: #20: identifier "SystemCoreClock" is undefined
- 解决步骤1:在FreeRTOSConfig.h中添加芯片头文件 #include "gd32f4xx.h"
- 解决步骤2:将下面代码替换工程内的代码
-
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) #include <stdint.h> extern uint32_t SystemCoreClock; #endif
- 解决步骤3:在工程内配置系统时钟的地方,设置滴答定时器时钟频率等于系统时钟,我的芯片通过以下库函数完成配置,其他芯片选择自己的库函数,结合时钟树完成配置。
-
systick_clksource_set (SYSTICK_CLKSOURCE_HCLK);
-
解决步骤4:为步骤3的库函数添加标准库,如下图所示
- 继续编译,报错消失,出现新的报错,这三个错误是因为这三个中断函数,freertos有自己的实现,去芯片的库内注释掉即可。
.\Objects\GD32F450.axf: Error: L6200E: Symbol SVC_Handler multiply defined (by port.o and gd32f4xx_it.o).
.\Objects\GD32F450.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by port.o and gd32f4xx_it.o).
.\Objects\GD32F450.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by port.o and gd32f4xx_it.o).
-
- 继续编译,以上报错消失,出现新的报错,如下。
-
.\Objects\GD32F450.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o). .\Objects\GD32F450.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o). .\Objects\GD32F450.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o). .\Objects\GD32F450.axf: Error: L6218E: Undefined symbol vApplicationMallocFailedHook (referred from heap_4.o).
- 解决方法:以上功能在FreeRTOSConfig.h打开了,但是工程内并没有实现,直接去关掉即可,按照我下图实现。如何有需要,自行打开即可。
- 再编译,全部报错消失。
- 建议把delay_ms函数修改一下,在它的文件内引用头文件,并使用freertos的延时代替原本的函数内容。这样使用更方便,移植其他模块时更方便。
-
#include "FreeRTOS.h" #include "task.h" void delay_1ms(uint32_t count) { vTaskDelay(count); // delay = count; // while(0U != delay) { // } }
freertos验证
测试代码
使用freertos的文件需要引用头文件
#include "FreeRTOS.h"
#include "task.h"
在头文件中验证如下:
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include <stdint.h>
#include "main.h"
#include "sys.h"
#include "lcd_169_spi.h"
#include "gd32f4xx_rcu.h"
#include "FreeRTOS.h"
#include "task.h"
static void Task1(void * pvParameters)
{
char task1Str[10] = {0};
int task1Count = 0;
lcd169_init();
lcd169_draw_rectangle_filled(0,0,LCD_X_PIXEL,LCD_Y_PIXEL,WHITE);
lcd169_sl_display_ascii_strings(60,10,SONG_24,"freertos测试",RED,WHITE);
while(1)
{
task1Count++;
sprintf(task1Str,"task1 : %d \r\n",task1Count);
lcd169_sl_display_ascii_strings(10,210,SONG_24,task1Str,RED,WHITE);
if(task1Count == 10000)
{
task1Count = 0;
}
vTaskDelay(1000);
}
}
static void Task2(void * pvParameters)
{
char task2Str[10] = {0};
int task2Count = 0;
while(1)
{
task2Count++;
sprintf(task2Str,"task2 : %d \r\n",task2Count);
lcd169_sl_display_ascii_strings(10,250,SONG_24,task2Str,RED,WHITE);
if(task2Count == 10000)
{
task2Count = 0;
}
vTaskDelay(1000);
}
}
static void TaskCreate()
{
TaskHandle_t xHandle = NULL;
TaskHandle_t xHandle2 = NULL;
xTaskCreate( Task1,
"Task1Name",
1000,
NULL,
1,
&xHandle
);
xTaskCreate( Task2,
"Task2Name",
1000,
NULL,
1,
&xHandle2
);
/* 启动调度器 */
vTaskStartScheduler();
}
int main(void)
{
systick_config();
TaskCreate();
while(1) {}
}
测试结果
两个任务分别累加计数,实验现象与预期一致,freertos移植成功。
移植验证可以使用屏幕、串口、led、GPIO等等都可以,或者直接使用keil内的逻辑分析仪 或者 IAR的 live watch,只需要能验证任务正常调度即可。
freertos的进一步介绍
暂时没时间,之后补充..