GD32E503的RT-Thread移植之工程创建
工程环境简介
GD32E503
笔者采用的是国内兆易创新的GD32E503R_START开发板,该开发板搭载的是基于Arm® Cortex®-M33内核的32位通用微控制器(MCU)的GD32E503RE。
片内主频可达180Mhz,片上Flash为512KB,SRAM为128KB。做RT-Thread的试验应该是没啥问题的。
RT-Thread
RT-Thread 是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权。
RT-Thread 主要采用 C 语言编写,浅显易懂,方便移植。它把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。针对资源受限的微控制器(MCU)系统,可通过方便易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 版本。
KEIL5.31
笔者使用的是Win10系统上安装的Keil5IDE开发工具。支持ARM Compiler V5和V6两个版本,编译器的差别请自行查阅官方相关资料(英文看着脑壳疼),反正就是V6在优化性能上更牛笔了。而且官方GD32E503的软件包貌似默认的是V6的编译器,详情笔者没去了解。
搭建开发环境
IDE安装
Keil的安装过程笔者就不赘述了,网上有一大把。
实验通信工具安装
GD32E503R_START使用的是CMSIS-DAP Debugger调试器
串口工具的驱动啥的也不说了。
软件包下载安装
需要到Keil MDK5 软件包界面
找到 GigaDevice.GD32E50x的软件支持包,

版本可按照自己的需求自行选择,笔者使用的是V1.3.1

然后找到RT-Thread 的软件支持包

笔者使用是最新的V3.1.5,刚好这个版本加入了支持M33的特性。

软件包安装完成后开始创建试验工程。
工程创建
新建工作目录

笔者的工程目录下新建了三个文件夹用于存放芯片外设的驱动文件,用于存放IDE自动生成的工程文件,用于存放包括主程序文件在内的应用文件。
创建Keil工程
在文件夹中创建“StartProj”工程文件。
Device
在Options->Device中设置如下

C/C++(AC6)
在Options->C/C++(AC6)中设置如下

Debug
在Options->Debug中设置如下

点击Options->Debug->Settings进入调试器设置界面。

为避免通信故障,通信速度可以适当的调慢。
Manage Run-Time Environment
在Manage Run-Time Environment界面中配置软件包选项;
GD32E503的选项如下


RT-Thread的选项如下,仅选择其内核功能。

配置rtconfig.h文件
在rtconfig.h的“Configuration Wizard”选项界面中设置OS tick 为1ms,Console、FinSH、Device功能关闭。

SysTick初始化
在board.c 文件中初始化SysTick, 并设置其中断,代码如下
//board.c
···
//Systick中断处理
void SysTick_Handler(void)
{
rt_interrupt_enter();
rt_tick_increase();
rt_interrupt_leave();
}
/**
* This function will initial your board.
*/
void rt_hw_board_init(void)
{
//#error "TODO 1: OS Tick Configuration."
/*
* TODO 1: OS Tick Configuration
* Enable the hardware timer and call the rt_os_tick_callback function
* periodically with the frequency RT_TICK_PER_SECOND.
*/
/* NVIC Configuration */
#define NVIC_VTOR_MASK 0x3FFFFF80
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x10000000 */
SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
SCB->VTOR = (0x08000000 & NVIC_VTOR_MASK);
#endif
// Systick 初始化
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
···
}
创建main函数
创建Main.c文件添加到工程下后,创建两个点亮开发板上的LED灯的任务,并在主程序中运行,代码如下。
// Main.c
#include "gd32e50x.h"
#include "rtthread.h"
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
static rt_thread_t tid1 = RT_NULL;
/* 线程 1 的入口函数 */
static void thread1_entry(void *parameter)
{
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10);
gpio_bit_reset(GPIOA, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10);
}
ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
/* 线程 2 入口 */
static void thread2_entry(void *param)
{
rt_thread_delay(500);
gpio_bit_set(GPIOA, GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10);
rt_thread_delay(500);
gpio_bit_reset(GPIOA, GPIO_PIN_8);
}
/* 线程示例 */
int thread_sample(void)
{
/* 创建线程 1,名称是 thread1,入口是 thread1_entry*/
tid1 = rt_thread_create("thread1",
thread1_entry, RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY, THREAD_TIMESLICE);
/* 如果获得线程控制块,启动这个线程 */
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
/* 初始化线程 2,名称是 thread2,入口是 thread2_entry */
rt_thread_init(&thread2,
"thread2",
thread2_entry,
RT_NULL,
&thread2_stack[0],
sizeof(thread2_stack),
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
rt_thread_startup(&thread2);
return 0;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(thread_sample, thread sample);
int main(void)
{
thread_sample();
}
编译结果:

结语
从编译结果看到 RT-Thread内核运行至少需要8K的flash空间及20K的RAM空间。
本文实现基本的RT-Thread内核移植和工程创建,任务切换及其他功能在后面章节详述。

本文详细介绍了如何在GD32E503R_START开发板上移植RT-Thread实时操作系统,包括开发环境的搭建,如安装Keil5IDE,配置软件包,创建工程,设置rtconfig.h文件,初始化SysTick以及创建主函数。文章还提到了RT-Thread的内存需求和基本任务切换的准备。
142

被折叠的 条评论
为什么被折叠?



