欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

STM32正点原子HAL库移植RT-Thread

程序员文章站 2022-03-15 12:08:41
我用正点原子F1的HAL库去移植, 用的串口例程,但是因为正点原子串口例程没有实现能和RT接口对接的字符串发送与接收,所以需要重新写, 我直接使用了RT官方做的32串口函数。一、RT*Thread移植1.首先准备好例程,改好文件名,最好不要有中文。2.准备好RT官方下载的STM32F103的例程,链接在这里:https://www.rt-thread.org/document/site/tutorial/quick-start/stm32f103-simulator/stm32f103-simul...

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

一、RT*Thread移植

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

STM32正点原子HAL库移植RT-Thread

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

https://www.rt-thread.org/document/site/tutorial/quick-start/stm32f103-simulator/stm32f103-simulator/

3.在工程文件夹里先建文件夹,RT-Thread

4.将官方程序程序rt-thread文件夹中的四个文件夹全部考到工程目录刚才建的那个文件夹中STM32正点原子HAL库移植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和SYSTEMSTM32正点原子HAL库移植RT-Thread

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

13.这里是Application里的文件

STM32正点原子HAL库移植RT-Thread

14.这里是Drivers里的文件

STM32正点原子HAL库移植RT-Thread

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

STM32正点原子HAL库移植RT-Thread

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

STM32正点原子HAL库移植RT-Thread
STM32正点原子HAL库移植RT-Thread

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

STM32正点原子HAL库移植RT-Thread

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

STM32正点原子HAL库移植RT-Thread

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

STM32正点原子HAL库移植RT-Thread

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

STM32正点原子HAL库移植RT-Thread

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

21.再编译,有4个错误

STM32正点原子HAL库移植RT-Thread

有几个中断函数重定义了,去这个函数里屏蔽掉STM32正点原子HAL库移植RT-Thread
STM32正点原子HAL库移植RT-Thread
STM32正点原子HAL库移植RT-Thread

22.再编译还有个错误, 是因为Drivers这个组里board.c里重复定义了void HAL_MspInit(void) 这个函数, 直接删除吧STM32正点原子HAL库移植RT-Thread

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上打开,拉到最下面将芯片改为你使用的,我用的是103C8STM32正点原子HAL库移植RT-Thread

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

STM32正点原子HAL库移植RT-Thread

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

STM32正点原子HAL库移植RT-Thread

DialongDLL:DARMSTM.DLL
Parameter:-pSTM32F103C8

29.MDK改成软件仿真,进入Debug

STM32正点原子HAL库移植RT-Thread

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里,

STM32正点原子HAL库移植RT-Thread

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

3.这是.c文件的代码

#include "rt_taskinit.h"

#include "rtthread.h"
#include "rtconfig.h"
#include <stdio.h>
#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

5.在main文件中调用这个头文件;

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

6.创建线程相关的函数我都写了注释哦。

本文地址:https://blog.csdn.net/qq_21479819/article/details/107964878