GD32F303移植FreeRTOS

GD32F303移植FreeRTOS

一、移植环境
系统:WIN7
MDK:keil v5.26
开发板:GD32F303C-EVAL
固件库:V1.0.2
FreeRTOS版本:V10.4.0
二、复制FreeRTOS到工程文件中
1> FreeRTOS简要介绍
FreeRTSO下载链接:https://www.freertos.org/a00104.html
在这里插入图片描述
将下载的文件解压,内容如下:FreeRTOS就是我们需要移植用到的,里面包含了官方移植的demo和内核文件,FreeRTOS-Plus里面包含了一些第三方的组件。
在这里插入图片描述
FreeRTOS文件夹内容如下:Demo文件夹下是官方在开发板移植好的demo,可以参考,Source文件夹下就是我们需要移植的内核文件。
在这里插入图片描述
Source文件夹内容如下:

内核文件

2> 在准备好的工程下创建一个FreeRTOS文件夹下,将1>提到的Source文件中所有的内容复制到这个文件夹下:
在这里插入图片描述
删除上图中红框中的内容,如下:
在这里插入图片描述
在当前目录下新建一个文件夹src,将红框中的内容剪切到src文件夹下,如下图:
在这里插入图片描述
进入到portable文件夹下,只保留下图三个文件夹,其余全部删除,如下图:
在这里插入图片描述
其中keil文件夹下没有可以用的内容,MemMang下是官方给的5种内存管理的方法,没有好坏之分,都有优缺点,根据需要选一种方式即可。
三、添加FreeRTOS文件到工程
1> 添加src下的文件到工程
在这里插入图片描述
2> 添加portable/MemMang/heap_4文件到工程
在这里插入图片描述
3> 添加portable/RVDS/ARM_CM4F/port文件到工程,因为GD32F303内核是Cortex-M4F内核。
在这里插入图片描述
4> 添加相应的头文件路径
在这里插入图片描述
5>编译一下,提示如下错误
在这里插入图片描述
缺少FreeRTOSConfig.h这个头文件,我们在FreeRTOS源码中复制一个将这个路径下的(FreeRTOS\FreeRTOS\Demo\CORTEX_STM32F103_Keil)FreeRTOSConfig.h文件复制到工程中,并且添加到工程中,如下图:
在这里插入图片描述
6>再次编译,提示如下错误:
在这里插入图片描述
其实就是缺少一个宏定义,这里可以在FreeRTOSConfig.h中定义一个
在这里插入图片描述
再次编译发现没有错误了。
7>写一个简单的LED任务测试一下,如下图:

#include "gd32f30x.h"
#include "led.h"
#include "systick.h"
#include <stdio.h>

#include "FreeRTOS.h"
#include "task.h"

#define LED1_TASK_PRIO    ( tskIDLE_PRIORITY + 2 )

void LED1_task(void * pvParameters);

int main(void)
{
	/* 设置优先级分组为4,16个优先级全是抢占优先级 */
    nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
	
	GW_LedInit(LED1);
	GW_LedInit(LED2);
	xTaskCreate(LED1_task, "LED1", configMINIMAL_STACK_SIZE, NULL, LED1_TASK_PRIO, NULL);
	/* start scheduler */
    vTaskStartScheduler();
    while(1){
    }
}
void LED1_task(void * pvParameters)
{  
    for( ;; ){
        /* toggle LED2 each 500ms */
        GW_LedToggle(LED1);
        vTaskDelay(300);
    }
}

下载到开发板,发现并没有LED运行,仿真调试发现,MCU进入了硬件中断,如下图:
在这里插入图片描述
这里我们仔细看一下,FreeRTOSConfig.h这个文件的配置,源码如下:

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/*-----------------------------------------------------------
 * Application specific definitions.
 *
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 *
 * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
 * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 
 *
 * See http://www.freertos.org/a00110.html
 *----------------------------------------------------------*/

#define configUSE_PREEMPTION		1
#define configUSE_IDLE_HOOK			0
#define configUSE_TICK_HOOK			0
#define configCPU_CLOCK_HZ			( ( unsigned long ) 72000000 )	
#define configTICK_RATE_HZ			( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES		( 5 )
#define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN		( 16 )
#define configUSE_TRACE_FACILITY	0
#define configUSE_16_BIT_TICKS		0
#define configIDLE_SHOULD_YIELD		1

由上面代码可以看出,这里系统时钟是需要更改的,configCPU_CLOCK_HZ这个是系统时钟,GD32F303是120Mhz的主频;configTOTAL_HEAP_SIZE设置堆得大小,这里设置了17KB的大小,而在启动代码里,堆设置了1KB,栈的大小也是设置的1KB,***注意:这三者的总和不能超过MCU自身的RAM大小。***如下图:
在这里插入图片描述
这里,我们将启动文件里的堆改成0x00000200(0.5KB),configTOTAL_HEAP_SIZE也更改成20KB,更改如下:

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include "gd32f30x.h"
/*-----------------------------------------------------------
 * Application specific definitions.
 *
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 *
 * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
 * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 
 *
 * See http://www.freertos.org/a00110.html
 *----------------------------------------------------------*/
extern uint32_t SystemCoreClock;

#define configUSE_PREEMPTION		1
#define configUSE_IDLE_HOOK			0
#define configUSE_TICK_HOOK			0
#define configCPU_CLOCK_HZ			( ( unsigned long ) SystemCoreClock )	
#define configTICK_RATE_HZ			( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES		( 5 )
#define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 20 * 1024 ) )
#define configMAX_TASK_NAME_LEN		( 16 )
#define configUSE_TRACE_FACILITY	0
#define configUSE_16_BIT_TICKS		0
#define configIDLE_SHOULD_YIELD		1

接下来编译进行下载,发现依旧会进入硬件中断,这就可能让人很崩溃了,这里需要了解一下FreeRTOS在Cortex内核中如何实现任务切换的机制,这里可以参考SVC & PendSV这篇博客,总的来说,既然想实现任务切换,就需要重新写这两个函数,之后在查看一下内核文件port.c,发现这里已经帮我们写好了,那就简单了,我们将gd32f30x_it.c文件里这两个中断函数给删掉,如下:
在这里插入图片描述
这里再次进行仿真下载调试,本以为可以万事大吉了,却还是被显示狠狠打脸了,仿真发现,程序死在了下面的循环中:
在这里插入图片描述
如上图,程序死在了SVC_Handler中断这,而我们上一步是把这个函数给删了,因为在上一步操作时,我们分析,内核文件port.c中帮我们重新写了这个函数,我们找到这个对应的函数如下:
在这里插入图片描述
呵呵,这就尴尬了,官方写的这个函数名称和启动文件中的中断入口函数名称不一致,既然如此,只能让这两个函数名联系到一起才行,我们在FreeRTOS.h中添加如下代码:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler

这下总应该可以了吧,下载编译,发现灯点亮了,心里那个开心啊,可是下一秒哭的心都有了,创建的任务是灯闪烁,现在灯只是点亮了并没有闪烁。仿真调试,发现如下:
在这里插入图片描述
看到这个现象,心情放松了一下,和之前现象类似,那我们接着去port.c文件去找一下,果真被我找到了:如下:
在这里插入图片描述
那仿照之前的操作,在FreeRTOSConfig.h中添加:

#define xPortSysTickHandler SysTick_Handler

LED终于亮了,至此,FreeRTOS最基本的移植完成。

工程下载链接:GD32F303_FreeRTOS10400

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值