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.首先准备好例程,改好文件名,最好不要有中文。
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 <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
上一篇: 工业DTU都有哪些强大的功能及特点