RT-THREAD移植-基于STM32F103RC

RT-Thread简介

RT-THREAD是国内开发的开源嵌入式操作系统,除了最基本的任务调度,线程同步,内存,中断管理等内核任务,还在源码包里面嵌了很多设备的驱动,设备使用模块化。
还有FinSH控制台,ULOG,UTEST等种种框架,如果用户有需要的使用可以达到很方便的集成与使用。
与其他操作系统内核相比,RT-THREAD提供了很多中间层,对于用到的用户来说,是很方便的事。不过对于新手来说,刚开始使用会觉得比较复杂。
官方还提供了相应的配置工具,基于python的图形配置命令来配置BSP层级参数。
作为用户将RT-THREAD移植到我们自己的板子上,只需从源码包里面将我们使用的代码包含到我们的工程就可以,至于代码级的细节操作,厂家都已经帮我们完成,我们加进来编译就可以使用
可能对具体的线路板做很轻微的调整。
RT-Thread 系统完全开源,遵循 Apache License 2.0 开源许可协议,可以免费在商业产品中使用,并且不需要公开私有代码,没有潜在商业风险。
当然更详细的介绍可以去看下官方的解释,这里是传送门RT-THREAD简介

基于STM32F103RC移植,RT-THREAD 4.10

这里我们只做把RT-THREAD移植到我们的工程里面去,至于RT-THREAD具体是如何实现调度与线程部分的操作,以及其他的复杂的中间件操作不作解释。只是先用下

新建工程

配置调试接口,添加外部晶振,生成工程,生成工程时不生成MAIN函数,当然也可以生成MAIN函数,只是初始化机制的原因MAIN中生成的函数,可能会影响到一些初始化设置的问题,因为这个MAIN是比较后面才被调用。



在生成代码的时候,因为RT-THREAD已经做了很多中断响应的函数操作,所以在生成代码的时候,不能生成systick等的中断响应函数,不然编译时会提示重复定义,像其他一些实时系统是通过改变中断向量名称与响应函数名称的方式实现。

添加RT-THREAD代码

源码结构

rt-thread-4.1.0/src  //内核代码
rt-thread-4.1.0/libcpu //cpu 相关代码 包含汇编,上下文切换,选择相关平台的代码用于工程即可
rt-thread-4.1.0/components //中间件代码,设备类,finsh,lwp等
rt-thread-4.1.0/bsp  //板级代码

添加内核代码

在新建的工程中新添加内核代码(rt-thread-4.1.0\src)及平台CPU移植代码(rt-thread-4.1.0\libcpu\arm\cortex-m3)如下图所示

不过此时这样编译还是通不过的,还要加上相关其他的配置。从官方例子中提取相关的配置文件加入到我们的工程中,组合成完善的可用的工程。

添加板级代码

以这个例子为例rt-thread-4.1.0\bsp\stm32\stm32f103-atk-warshipv3,先复制RTTHREAD的配置文件rtconfig.h至我们的工程
从rt-thread-4.1.0\bsp\stm32\stm32f103-atk-warshipv3\board复制相应的板定义代码
从rt-thread-4.1.0\bsp\stm32\libraries\HAL_Drivers复制需要用到的STM32相关的设备驱动代码,
用这里的代码,其实我们可以不用再调用CUBEMX生成函数,调用这里的设备代码也可以,因为他们会调用HAL库的接口
针对当前工程,最后所需的文件如下图所示,可以直接从源码包里面引用出来,也可以拷出来方便修改。

添加设备机制相关代码

在加入这些板级代码的同时,还要添加相关被使用到的代码,因为这些板级代码有用到RT-THREAD内的一些机制来实现相关的功能,数据队列等等
目录如下
rt-thread-4.1.0\components\drivers\ipc
rt-thread-4.1.0\components\drivers\misc
rt-thread-4.1.0\components\drivers\serial

添加finsh代码

在RT-THREAD的配置文件里面添加FINSH功能,因此也要这些代码添加至工程
rt-thread-4.1.0\components\finsh

至此代码已经添加完毕。

代码调整至当前工程

编译时发现SystemClock_Config重定义,这时需要将board.c中的SystemClock_Config定义注释掉,因为CUBEMX改变时,board.c里的函数不会改变,自动生成的则可以。
修改board.h文件里面的配置,来符合F103RC的参数,这里的数据定义会影响到内存动态分配时使用,这里必须要与芯片一致

#define STM32_FLASH_START_ADRESS     ((uint32_t)0x08000000)
#define STM32_FLASH_SIZE             (256 * 1024)
#define STM32_FLASH_END_ADDRESS      ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE))

/* Internal SRAM memory size[Kbytes] <8-64>, Default: 64*/
#define STM32_SRAM_SIZE      48
#define STM32_SRAM_END       (0x20000000 + STM32_SRAM_SIZE * 1024)

rtconfig.h

#define SOC_STM32F103RC

这样就完成最基本的修改了,编译通过应该就可以跑起RT-THREAD,当然如果编译时提示其他的编译错误,可以提示解决即可。

添加LED闪烁任务

#include "rtthread.h"
#include "rtdevice.h"

#define LED_PIN 0x01
/*********************************************************
*********************************************************/
void Led_Entry(void *parameter)
{
	rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
	while(1)
	{
		rt_pin_write(LED_PIN, PIN_HIGH);
		rt_kprintf("Led On\n");
		rt_thread_mdelay(1000);
		rt_pin_write(LED_PIN, PIN_LOW);
		rt_kprintf("Led Off\n");
		rt_thread_mdelay(1000);
	}
}

/*********************************************************
*********************************************************/
int Led_Test(void)
{
	static rt_thread_t tid1;
	tid1 = rt_thread_create("led",
					Led_Entry,RT_NULL,
					256,
					20,5);

	if(tid1 != RT_NULL)
		rt_thread_startup(tid1);
	return 0;
}
INIT_APP_EXPORT(Led_Test);

软件仿真

软件设置

此时可以进行软件仿真尝试,如果看到这样的效果就可以认定RT-THREAD的跑起来了。当然用实际的UART来跑应该也是没有问题的。

总结

RT-THREAD基于常用的MCU移植来说是比较方便的,因为厂家把工作都做好了,我们只需要拿过来用就可以了。
同时RT-THREAD的功能是比较多的,对初学者来说比较麻烦,
以及用宏定义来进行初始化的操作,对于习惯直接调用的使用者来说刚开始可能不太习惯。
具体的使用细节在使用中慢慢探索。

posted @ 2022-10-18 09:18  cau_par  阅读(636)  评论(0编辑  收藏  举报