STM32
直播中

徐磊

7年用户 900经验值
私信 关注
[问答]

如何移植RT-Thread?

如何移植RT-Thread?

回帖(1)

赖治添

2021-11-29 11:09:12
我用正点原子F1的HAL库去移植, 用的串口例程,但是因为正点原子串口例程没有实现能和RT接口对接的字符串发送与接收,所以需要重新写, 我直接使用了RT官方做的32串口函数。

一、RT*Thread移植

1.首先准备好例程,改好文件名,最好不要有中文。






2.准备好RT官方下载的STM32F103的例程,链接在这里:

https://www.rt-thread.org/document/site/tutorial/quick-start/stm32f103-simulator/stm32f103-simulator/
3.在工程文件夹里先建文件夹,RT-Thread

4.将官方程序程序rt-thread文件夹中的四个文件夹全部考到工程目录刚才建的那个文件夹中





5.然后将drivers文件夹考到工程跟目录下

6.官方根目录下有rtconfig.h,也放到工程drivers文件夹中

7.删除drivres文件夹下的 stm32开头的3个文件

8.重构工程文件夹,根目录下新建Application文件夹(这个文件夹存放应用)

9.将HARDWARE中的key.c+key.h 和led.c+led.h还有SYSTEM文件夹中sys.c+sys.h都放到刚才新建的Application文件夹中

10.删除HARDWARE和SYSTEM文件夹(到这里要移植的文件已经移植完了)

11.打开工程的MDK文件,重新建立组别删除HAREWARE和SYSTEM





12.新建Applications(存放应用函数),Drivers(用户驱动),Kernel(RT内核),Coretx-M3(芯片指令集文件),DeviceDrivers(RT官方驱动),finsh(命令行文件)。 新建这几个组,分别将不同文件导入;

13.这里是Application里的文件






14.这里是Drivers里的文件






15.这里存放RT-Thread-src里的所有.c文件






16.这里存放RT-Thread里libcpu的文件, (注意这里要把汇编的.s文件加进去,注意文件)











17.这里存放RT-Thread-conponents里的drivers里的 misc和serial里两个.c文件






18.这里存放finsh里的所有文件






19.文件全部导入工程开始添加头文件路径,






20.然后编译一下,我这里显示,正常有2个错误0个警告






双击找BUG,一个是调用了delay.h头文件, 因为刚才咱们已经删除了所以这里直接注释掉或者删除,
另外一个是main文件中调用了delay.h头文件直接删除这句代码
顺带删除主函数中所有内容, 只留下main的框架,





21.再编译,有4个错误






有几个中断函数重定义了,去这个函数里屏蔽掉














22.再编译还有个错误, 是因为Drivers这个组里board.c里重复定义了void HAL_MspInit(void) 这个函数, 直接删除吧





23.在board.c中加入这三个头文件

24.然后把void rt_hw_board_init(void) 函数的内容改成这个,


void rt_hw_board_init(void)
{
    HAL_Init();
    Stm32_Clock_Init(RCC_PLL_MUL9);                                                 //????,72M       
    SystemClock_Config();
        SysTick_Config(SystemCoreClock/RT_TICK_PER_SECOND);                //??????
#ifdef RT_USING_HEAP
    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif
#ifdef RT_USING_CONSOLE
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
}
25.然后再编译,还有个错误, 是因为key.c中调用了 delay_ms(10);

Delay.c咱们都删除了这个肯定会报错,先删除这一行,再编译
26.打开board.c在头文件 rtconfig.h上打开,拉到最下面将芯片改为你使用的,我用的是103C8





27.将RT_TICK_PER_SECOND 改为1000,保存重新编译。






28.已经显示没有错误啦, 这时候可以用虚拟串口试一下,不过MDK在DEbug这里要改两个选项,才能使用虚拟串口






DialongDLL:DARMSTM.DLL
Parameter:-pSTM32F103C8
29.MDK改成软件仿真,进入Debug






30.这里就已经完成了对于RT-Thread的移植,在右边串口中按Tab键就可以弹出命令行,快点开始学习RT-Thread吧

31.对了这里printf函数需要重新实现以下,去Drivers组里的usart.c后面加上这段代码;


typedef struct __FILE FILE;


#if 1
#pragma import(__use_no_semihosting)            
//±ê×¼¿âÐèÒªµÄÖ§³Öº¯Êý                 
struct __FILE
{
        int handle;


};


FILE __stdout;      
//¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ   
void _sys_exit(int x)
{
        x = x;
}
//Öض¨Òåfputcº¯Êý
int fputc(int ch, FILE *f)
{      
        while((USART1->SR&0X40)==0);//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
    USART1->DR = (uint8_t) ch;      
        return ch;
}
#endif
  保存然后编译。
二、RT-Thread任务创建

1.建立一个rt_taskinit.c 和.h的文件,在drivers里,






2.将文件添加工程中drivers的组中,在rt_taskinit.c中加入#include “stdio.h”头文件,

3.这是.c文件的代码

#include "rt_taskinit.h"


#include "rtthread.h"
#include "rtconfig.h"
#include
#include "sys.h"
#include "led.h"


/*******************************************************
*
*                   线程创建
*
********************************************************/
    /*第一线程*/
void rt_task1(void *parameter)
{
    while(1)
    {
        printf("taskone n");
         LED0=0;
         rt_thread_delay(RT_TICK_PER_SECOND);
    }
}


    /*第二线程*/
void rt_task2(void *parameter)
{
    while(1)
    {
        printf("tasktow n");
         LED0=1;
         rt_thread_delay(RT_TICK_PER_SECOND);
    }
}


/*******************************************************
*
*                   线程初始化
*
********************************************************/
void rt_taskinit()
{
/*************************创建线程******************************/
    /*创建线程1*/
    rt_thread_t task1;
    /*创建线程2*/
    rt_thread_t task2;
   
/***************************线程参数设置************************************/
    /*函数参数,1.线程名字,2.线程入口函数名,3。线程入口参数 4.线程栈大小 5.线程优先级 6.线程tick数*/
    task1=rt_thread_create("task1" ,rt_task1 ,RT_NULL ,200 ,7 ,1);
    /*函数参数,1.线程名字,2.线程入口函数名,3。线程入口参数 4.线程栈大小 5.线程优先级 6.线程tick数*/
    task2=rt_thread_create("task2" ,rt_task2 ,RT_NULL ,200 ,7 ,1);  
   
   
/*******************************线程初始化*******************************************/
        if(task1 !=RT_NULL)
    {
        rt_kprintf("task1 create success"); //如果创建失败打印出失败
        rt_thread_startup(task1);           //如果创建成功开始运行
    }
    else
    {
        rt_kprintf("task1 create fail");    //如果创建失败打印出失败
    }


   
        if(task2 !=RT_NULL)
    {
        rt_kprintf("task2 create success"); //如果创建失败打印出失败
        rt_thread_startup(task2);           //如果创建成功开始运行
    }
    else
    {
        rt_kprintf("task2 create fail");    //如果创建失败打印出失败
    }


}
4.这是.h文件的代码

#ifndef __RT_TASKINIT_H
#define __RT_TASKINIT_H


void rt_taskinit(void);


#endif
在main函数里调用 rt_taskinit();
然后编译,再仿真,
上面函数我创建了两个线程,会打印taskone 和tasktwo,(好吧把two打错了哈哈哈!)
rt_thread_delay(RT_TICK_PER_SECOND); 这个函数是一个rt库的里的延迟函数,参数是时间,这个参数可以跳转,它是1000,也就代表每秒1000次中断,然后咱们延时相当于1000个时间片,也就是1s,可以把函数的参数改成500,就是500ms一次。但是board.c中不要更改哦。
6.创建线程相关的函数我都写了注释哦。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分