在STM32F103ZET6上移植RT-Thread nano内核,使用keil作为开发环境。
**
1.准备工作
** 需要准备一份裸机工程,和RT-Thread nano源码: 裸机工程建议使用完整的工程,若使用keil创建,库文件并不在工程文件夹中,而是通过添加库路径进行引用的,可以直接去keil路径中将文件拷贝到工程文件中。为保证后续操作,建议将裸机下载试一下。
RT-Thread nano源码直接到官网下载就行 解压下载包,进入rtthread文件夹,得到系统的所有文件:
2.移植
2.1 删除与我们移植STM32无关的文件,bsp中我们仅保留board.c和rtconfig.h libcpu中,STM32属于ARM架构M3内核,所以仅保留arm及下的cortex-m3文件: 随后,将rtthread文件夹放入裸机工程中: 总结一下,实际上RTOS的文件可分为三部分: 第一部分:是板级相关的文件和系统配置文件,前者中主要是做一些板级的初始化,后者主要是通过修改宏或者相关数值来裁剪或者配置系统功能,在rtthread中即为bsp文件夹中的board.c和rtconfig.h。
第二部分:是系统文件,包括系统各个功能的源文件,如线程、通信、内存等,此处为src文件夹下的所有文件,此部分文件不需要修改。
第三部分:是芯片内核移植相关的文件(此处为cortex-m),这其中涉及ARM架构和操作系统的底层实现原理,实际上下载源码中官方已经对cortex-m做了适配移植。 按照三部分,将文件加入到keil工程,我是按照三部分,看起来直接一点,具体怎样放置文件没有绝对的规则。 2.2 测试系统 到此,实际上因为RTTHREAD做了相关的移植适配,系统到STM32F103ZET6的移植基本就好了,比如下图rt_hw_board_init()函数,下载官网的源码就已经写好了时钟配置和系统滴答时基的配置,如果通过keil软件包引入RTTHREAD还需要完成这两个函数。
void rt_hw_board_init()
{
SystemCoreClockUpdate();
_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
#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
}
在移植过程中,预计出现以下错误,参考解决办法如下: 错误解决: (1)删除头文件 RTE_Components.h,并注释掉rtconfig.h中对它的引用,它是在 MDK中添加 RT-Thead Package 时由 MDK 自动生成的,我们不使用keil的package,不删除会引发一个报错。 (2)注释掉stm32f10x_it.c中的HardFault_Handler(void),PendSV_Handler(void),SysTick_Handler(void),因为rtthread对它们进行了实现,不删除会导致重复定义错误。 (3)Error: L6218E: Undefined symbol rt_thread_create (referred from main.o),打开rtconfig.h中的堆使用宏#define RT_USING_HEAP ,系统中采用动态方式创建线程等等操作需要使用到堆,不然会出现以上错误。 (4)还有一个隐藏问题,下载的源码中,将任务数默认设置为8,所以测试代码时,若线程优先级低于8(数字大于8)时,会发现代码没有报错而线程无法运行,可通过修改宏定义 #define RT_THREAD_PRIORITY_MAX 32 更改线程数量,或者通过下图向导框修改,rtthread最高支持256
接下来点个灯测试一下,记得将相关的头文件路径配置好:
#include "led.h"
#include "stm32f10x_gpio.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Write(GPIOB,0);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
}
void led_on(void)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_5, 0);
}
void led_off(void)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_5, 1);
}
#include "led.h"
#include <rtthread.h>
rt_thread_t led_thread = RT_NULL;
void led_thread_entry(void* para)
{
while(1)
{
led_off();
rt_thread_mdelay(300);
led_on();
rt_thread_mdelay(100);
}
}
int main(void)
{
LED_Init();
led_thread = rt_thread_create("led",led_thread_entry, RT_NULL, 128, 20, 20);
if(led_thread != RT_NULL)
rt_thread_startup(led_thread);
return 0;
}
|