GD32E503的RT-Thread移植之工程创建

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

工程环境简介

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内核移植和工程创建,任务切换及其他功能在后面章节详述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ATC Working

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值