上一篇帖子尝试了移植FreeRTOS到GD32L233C并移植成功是实现了两个LED点灯任务:https://bbs.eeworld.com.cn/thread-1192482-1-1.html#pid3118101
本文将尝试使用国产的嵌入式实时操作系统RT-Thread,相比较于FreeRTOS,RT-Thread还是有很多有点的,比如果有Fish命令行界面,国产开源免费,Nano版本代码量极小,移植起来非常简单(比freeRTOS移植还简单)等,本文将讲解如何将RT-Thread Nano移植到GD32L233C。
注:本文基于KEIL编译器,IAR编译器可以参考文档:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-nano/nano-port-iar/an0040-nano-port-iar
一、获取RT-Thread基于KEIL的离线安装包
地址:https://www.rt-thread.org/download/mdk/RealThread.RT-Thread.3.1.5.pack
下载之后双击安装即可。
二、添加RT-Thread Nano到工程
三、修改文件适配Rt-Thread
我们需要修改HardFault_Handler() 和 PendSV_Handler(),这两个文件是由RT-Thread实现的,所以我们工程里面原来的这两个函数都需要删除掉,屏蔽掉这两个函数的申明和定义:
四、修改系统时钟
RT-Thread已经为我们写好了时钟节拍函数rt_os_tick_callback(), 在board.c文件中,我们只需要将这个函数放置到SysTick_Handler()中即可,注意需要删除SysTick_Handler()中的原有内容。
删除rt_hw_board_init()函数中的#error信息,这个函数在board.c文件中,其目的是提醒用户移植的时候不要忘了心跳节拍的移植,这点还是很人性化的,免得移植了半天发现不工作。
五、修改时钟节拍
RT-Thread为我们提供的配置文件的时钟节拍是1000,也就是1ms,如果你想要修改心跳节拍,可以在rtconfig.h中修改这个宏RT_TICK_PER_SECOND,目前是1000,如果想修改节拍为10ms,则修改该值为10000,修改的时候最好不要直接修改rtconfig.h这个文件,因为KEIL提供了配置界面修改,在配置界面修改安全可靠。
六、创建线程测试移植是否成功
经过了上面的步骤,我们的移植已经算是完成了,接下来就是写程序验证了,像上一篇帖子一样,我们写两个LED动作的线程,LED1 100ms闪烁一次,LED2 500ms闪烁一次来做对比,别忘了修改LED灯的引脚,上一篇帖子已经说明白了,引脚不对,需要我们自己修改,如下:
在main.c中写两个线程,如下:
#include "gd32l23x.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "gd32l233r_eval.h"
#include <rtthread.h>
static rt_thread_t led1_thr = RT_NULL;
static rt_thread_t led2_thr = RT_NULL;
static void thread_led1_entry(void *parameter);
static void thread_led2_entry(void *parameter);
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
/* configure systick */
systick_config();
/* initilize the LEDs, USART and key */
gd_eval_led_init(LED1);
gd_eval_led_init(LED2);
led1_thr = rt_thread_create( "led1", /*线程名字*/
thread_led1_entry,/*线程入口函数*/
RT_NULL,/*线程入口函数参数*/
256, /*线程栈大小*/
4 , /*线程优先级*/
20); /*线程时间片*/
led2_thr = rt_thread_create( "led2", /*线程名字*/
thread_led2_entry,/*线程入口函数*/
RT_NULL,/*线程入口函数参数*/
256, /*线程栈大小*/
3 , /*线程优先级*/
20); /*线程时间片*/
rt_thread_startup (led1_thr);
rt_thread_startup (led2_thr);
while(1)
{
rt_thread_mdelay(100);
}
}
static void thread_led1_entry(void *parameter)
{
while (1)
{
gd_eval_led_toggle(LED1);
rt_thread_mdelay(100);
}
}
static void thread_led2_entry(void *parameter)
{
while (1)
{
gd_eval_led_toggle(LED2);
rt_thread_mdelay(500);
}
}
编译成功下载,发现程序并不运行,这是为什么呢?
通过堆问题的查找,发现是main函数线程的堆栈空间分配的太小了,因为相比较于其他嵌入式系统,RT-Thread将main函数也做为了一个线程,我们在main函数中创建线程需要较大的空间,而RT-Thread给的默认配置的main线程的堆栈空间为256,修改为512即可:
再次编译下载,成功,后期可以使用RT-Thread来开发多线程任务了。
七、演示
八、源码
有需要的小伙伴可以参考哦
如果本文有遗漏之处或者是错误之处,还请指正,谢谢
本帖最后由 hehung 于 2022-1-19 22:05 编辑