目录
- GD32F407移植FreeRTOS测试
- 一、基础代码与环境
- 二、移植
- 1、复制示例并改名
- 2、修改替换文件夹内容
- 3、创建文件夹并把freertos的文件粘贴进去
- 4、在kail里面先把需要的头文件的路径给加入进去(主要是下面三个路径)
- 5、创建目录组文件夹 FreeRTOSCore 和 FreeRTOSPort (分别为核心文件和接口文件的文件夹)
- 6、 把 CMSIS 和 Startup 的文件夹里面的文件删掉,在去下面文件路径找到该文件导入进去:
- 7、 把 FreeRTOSConfig 放入 FreeRTOS\include 文件夹里面
- 8、注释掉GD32的 SVC_Handler 和 PendSV_Handler
- 9、 重写 SysTick_Handler()
- 10、最后进行编译
- 三、测试代码的运行
- 四、总结
GD32F407移植FreeRTOS测试
一、基础代码与环境
文件路径:
标准库链接位置: 标准库
FreeRTOS链接位置: FreeRTOS
GD32F407资料链接: GD32F407资料
1、找到GD32的官方标准库下载
2、找到FreeRTOS 的官方示例代码下载
3、使用找到一个基础的点灯代码
点灯代码一般买开发板时问客服要这块开发板资料里面就有。
如果没有在这里下载 F407的代码资料:
链接: GD32F407资料
点灯代码:
二、移植
1、复制示例并改名
2、修改替换文件夹内容
- 把标准库的头文件复制替换原有的头文件夹CMSIS
- 替换的文件夹
3、创建文件夹并把freertos的文件粘贴进去
(1)创建一个名为FreeRTOS的文件夹到移植的主目录
(2)移植FreeRTOS文件
- 把FreeRTOS的文件里的Source里面的文件复制到刚刚创建的那个FreeRTOS里面(叉掉的那几个可以不用复制,只要.c文件和两个文件夹就行)
(3)删除portable文件里多余的文件夹只留下 (Keil 、MemMang、RVDS )三个文件夹
- 到这里所有需要的文件已经放到主目录下面了
4、在kail里面先把需要的头文件的路径给加入进去(主要是下面三个路径)
5、创建目录组文件夹 FreeRTOSCore 和 FreeRTOSPort (分别为核心文件和接口文件的文件夹)
- 7个核心文件和 2个接口文件
- 接口文件路径1:FreeRTOS\portable\RVDS\ARM_CM4F
- 接口文件路径2:FreeRTOS\portable\MemMang
- 接口文件路径3:FreeRTOS
文件在这几个路径里面找:
6、 把 CMSIS 和 Startup 的文件夹里面的文件删掉,在去下面文件路径找到该文件导入进去:
- 文件路径1: CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c
- 文件路径2: CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f407_427.s
7、 把 FreeRTOSConfig 放入 FreeRTOS\include 文件夹里面
- 一般 FreeRTOSConfig 文件是需要根据自己的情况来写的,但是如果没有的话到我给的那个资料里面找:
- 位置:GD32F407VET6开发板资料和例程\例程代码\13.FREERTOS实验\FreeRTOS\include
- 复制到 主目录下的 FreeRTOS\include 里面:
8、注释掉GD32的 SVC_Handler 和 PendSV_Handler
- 这两个函数在 FreeRTOS里面已经有单独的实现了,所有不注释掉他们就会与FreeRTOS的文件冲突。
- 函数所在的文件:gd32f4xx_it.c
9、 重写 SysTick_Handler()
-
注释掉 gd32f4xx_it.c 里面的 SysTick_Handler
-
在 systick.c 里面重写 SysTick_Handler
//systick.c
//需要先导入头文件
#include "FreeRTOS.h"
#include "task.h"
extern void xPortSysTickHandler(void);
//滴答定时器的回调函数,给freertos提供时基
void SysTick_Handler(void){
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
{
xPortSysTickHandler();
}
}
10、最后进行编译
- 编译无报错就移植成功了
三、测试代码的运行
- 下面是个mian函数里面调用 freertos(只要复制粘贴到mian就好了)
- 里面是一个点灯的实列
#include "gd32f4xx.h"
#include "gd32f4xx_libopt.h"
#include "systick.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 LED1_TASK_PRIO 3
//任务堆栈大小
#define LED1_STK_SIZE 50
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void LED_Thread1(void *pvParameters);
//任务优先级
#define LED2_TASK_PRIO 4
//任务堆栈大小
#define LED2_STK_SIZE 50
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void LED_Thread2(void *pvParameters);
int main(void)
{
systick_config();//配置系统主频168M,外部8M晶振,配置在#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL (uint32_t)(168000000)
rcu_periph_clock_enable(RCU_GPIOB);//使能GPIOB时钟
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_4);//PB4配置成输出
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);//PB4配置成推挽输出,50M速度
//创建开始任务
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(); //开启任务调度
}
//开始任务任务函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建LED1任务
xTaskCreate((TaskFunction_t )LED_Thread1,
(const char* )"led1_task",
(uint16_t )LED1_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED1_TASK_PRIO,
(TaskHandle_t* )&LED1Task_Handler);
xTaskCreate((TaskFunction_t )LED_Thread2,
(const char* )"led2_task",
(uint16_t )LED2_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED2_TASK_PRIO,
(TaskHandle_t* )&LED2Task_Handler);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//LED1任务函数
void LED_Thread1(void *pvParameters)
{
while(1)
{
gpio_bit_set(GPIOB, GPIO_PIN_4);//PB4输出高电平
vTaskDelay(100);
}
}
//LED2任务函数
void LED_Thread2(void *pvParameters)
{
while(1)
{
gpio_bit_reset(GPIOB, GPIO_PIN_4);//PB4输出低电平
vTaskDelay(250);
}
}
最后编译烧录到开发板就好了。成功以后开发板就会有一颗灯一闪一闪的。
注意:开发板烧录完后记得按复位键,不然不会运行程序。
四、总结
这是一次GD32移植Freertos的示例,其他的GD32开发板也可以参照这个来移植。
主要大体移植步骤:
(1) 把需要的文件和文件夹放入主目录
(2) 在keil里面导入头文件路径
(3) 导入需要的freertos文件(7个核心文件2个接口文件)
(4) 提供时基 修改滴答定时器的回调函数 SysTick_Handler (一般为 1ms 调用 1次),不一定要使用滴答定时器,只需要能提供1ms调用1次的定时器就行
(5) 写测试的代码,调用 FreeRTOS的任务
下面为滴答定时器的初始化:
//在这里面 1000 表示 1s 调用 1千次 就是1ms 1次
void systick_config(void)
{
/* setup systick timer for 1000Hz interrupts */
if (SysTick_Config(SystemCoreClock / 1000U)){
/* capture error */
while (1){
}
}
/* configure the systick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x00U);
}
//每1ms调用1次
void SysTick_Handler(void){
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
{
xPortSysTickHandler();
}
}
这次移植主要是熟悉下 FreeRTOS的移植,写个博客方便自己以后翻阅,不然以后忘记了,不好查。如有不足请在参考其他的移植。