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

我用正点原子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文件夹中的四个文件夹全部考到工程目录刚才建的那个文件夹中STM32正点原子HAL库移植RT-Thread_第1张图片

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_第2张图片

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

13.这里是Application里的文件

STM32正点原子HAL库移植RT-Thread_第3张图片

14.这里是Drivers里的文件

STM32正点原子HAL库移植RT-Thread_第4张图片

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

STM32正点原子HAL库移植RT-Thread_第5张图片

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

STM32正点原子HAL库移植RT-Thread_第6张图片
STM32正点原子HAL库移植RT-Thread_第7张图片

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

STM32正点原子HAL库移植RT-Thread_第8张图片

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

STM32正点原子HAL库移植RT-Thread_第9张图片

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

STM32正点原子HAL库移植RT-Thread_第10张图片

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

STM32正点原子HAL库移植RT-Thread_第11张图片

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

21.再编译,有4个错误

在这里插入图片描述

有几个中断函数重定义了,去这个函数里屏蔽掉在这里插入图片描述
STM32正点原子HAL库移植RT-Thread_第13张图片
STM32正点原子HAL库移植RT-Thread_第14张图片

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

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

STM32正点原子HAL库移植RT-Thread_第16张图片

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

STM32正点原子HAL库移植RT-Thread_第17张图片

DialongDLL:DARMSTM.DLL
Parameter:-pSTM32F103C8

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

STM32正点原子HAL库移植RT-Thread_第18张图片

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_第19张图片

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.创建线程相关的函数我都写了注释哦。

你可能感兴趣的:(笔记,stm32,嵌入式,qt,c语言,操作系统)