当前位置:   article > 正文

stm32移植rt-thread移植-作废_at32f移植rtthread

at32f移植rtthread

系统与工具、环境变量的配置

基础知识

需要了解学会使用Makefile,链接器脚本文件。使用CUBEMX生成初始文件

Makefile

#Makefile 里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释
#显式规则说明了,如何生成一个或多的的目标文件。这是由 Makefile 的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
# make 有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写 Makefile
# 变量一般都是字符串,这个有点你 C 语言中的宏,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。
# 注释是用“#”字符,只有行注释
# 在 Makefile 中的命令,必须要以[Tab]键开始
# Makefile 使用 include 关键字可以把别的 Makefile 包含进来
# include <filename> 
# make工作方式:
# 1、读入所有的 Makefile。 
# 2、读入被 include 的其它 Makefile。 
# 3、初始化文件中的变量。 
# 4、推导隐晦规则,并分析所有规则。 
# 5、为所有的目标文件创建依赖关系链。 
# 6、根据依赖关系,决定哪些目标要重新生成。 
# 7、执行生成命令。 
# 命令行可以单独以{TAB}开始,也可用分号与上放入一行。可使用\作为换行符号
# make 会以 UNIX 的标准 Shell,也就是/bin/sh 来执行命令
# 通配符:make 支持三各通配符:“*”,“?”和“[...]”。这是和 Unix 的 B-Shell 是相同的。
# “~/test”,这就表示当前用户的$HOME 目录下的 test 目录。而“~hchen/test”则表示用户 hchen 的宿主目录下的 test 目录。
# 文件搜寻 VPATH = 目录1:目录2
# 目录由“冒号”分隔
# “vpath”关键字:可以指定不同的文件在不同的搜索目录中。
# 1、vpath <pattern> <directories>	为符合模式<pattern>的文件指定搜索目录<directories>。 
# 2、vpath <pattern> 	清除符合模式<pattern>的文件的搜索目录。 
# 3、vpath 	清除所有已被设置好了的文件搜索目录。
# <pattern>需要包含“%”字符。“%”的意思是匹配零或若干字符
# “伪目标”并不是一个文件,只是一个标签,“伪目标”不是文件,显示地指明这个“目标”才能让其生效,取名不能和文件名重名
# 为了避免和文件重名的这种情况,使用“.PHONY”来显示地指明一个目标是“伪目标”,不管是否有这个文件,这个目标就是“伪目标”。 
# 静态模式:如
# $(objects): %.o: %.c 
# $(CC) -c $(CFLAGS) $< -o $@
# 目标从$object 中获取,“%.o”表明要所有以“.o”结尾的目标,也就是变量$object 集合的模式,而依赖模式“%.c”
# “$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集,“$@”表示目标集
# 自动生成依赖性:大多数的C/C++编译器都支持一个“-M”的选项,即自动找寻源文件中包含的头文件,并生成一个依赖关系
# GNU 组织建议把编译器为每一个源文件的自动生成的依赖关系放到一个文件中,都生成一个“.d”的 Makefile 文件存放对应[.c]文件的依赖关系
# %.d: %.c 
# @set -e; rm -f $@; \ 
# $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ 
# sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ 
# rm -f $@.$$$$ 
# 显示命令 “@”字符在命令行前,那么,这个命令将不被 make 显示出来.
# make 参数“-n”或“--just-print”,那么其只是显示命令,但不会执行命令
# 命令执行:你希望第二条命令得在 xx 之后的基础上运行,那么你就不能把这两条命令写在两行上,而应该把这两条命令写在一行上
# 忽略命令的出错,我们可以在 Makefile 的命令行前加一个减号“-”不管命令出不出错都认为是成功的
# 嵌套执行 make :
# 变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。
# “+=”操作符给变量追加值
# 自动化变量:
# $@ 表示规则中的目标文件集
# $% 仅当目标是函数库文件中,表示规则中的目标成员名
# $< 依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。
# $? 所有比目标新的依赖目标的集合。
# $^ 所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
# 另外有$+ $*

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

链接脚本

STM32HAL库也提供了相应MCU的启动文件和链接脚本,我们可以直接使用

STM32文件目录

CUBEMX生成的文件

.
├── Core
│   ├── Inc
│   │   ├── main.h
│   │   ├── stm32f1xx_hal_conf.h
│   │   └── stm32f1xx_it.h
│   └── Src
│       ├── main.c
│       ├── stm32f1xx_hal_msp.c
│       ├── stm32f1xx_it.c
│       └── system_stm32f1xx.c
├── CUBEMX-TEPM.ioc
├── Drivers
│   ├── CMSIS
│   │   ├── Core
│   │   ├── Core_A
│   │   ├── Device
│   │   ├── docs
│   │   ├── DSP
│   │   ├── Include
│   │   ├── Lib
│   │   ├── LICENSE.txt
│   │   ├── NN
│   │   ├── RTOS
│   │   └── RTOS2
│   └── STM32F1xx_HAL_Driver
│       ├── Inc
│       └── Src
├── Makefile
├── startup_stm32f103xb.s
└── STM32F103C8Tx_FLASH.ld
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

STM32启动分析

在这里插入图片描述
由于STM32MCU的启动代码与链接脚本在HAL库中直接提供了,因此我们可以直接进行使用。因此我们可以直接从main文件开始看代码的执行,汇编启动代码将跳至main函数

#include <main.h>
void SystemClock_Config(void);
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  while (1)
  {
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

系统初始化

系统时钟配置

//HAL库的功能宏在stm32f1xx_hal_conf.h可开启关闭
在这里插入图片描述

1.初始化HAL库HAL_Init();

-1.根据型号选择是否开启 预缓冲器
Flash通过AHB协议执行指令存取和数据存取,它以预存取缓冲的方式,加速CPU代码的执行
-2.设置中断优先寄存器组
中断优先寄存器组
-3.初始化 SysTick(滴答定时器)
使用systick作为时基源,并配置1ms中断(重置后的默认时钟为HSI)
-4.调用 HAL_MspInit回调函数,执行全局底层硬件初始化,这个函数由开发者自己完成。

2.系统时钟初始化SystemClock_Config();

  /*
  uint32_t OscillatorType;        // 时钟来源:HSE/HSI/LSE/LSI    @ref RCC_Oscillator_Type
  uint32_t HSEState;              // HSE状态          @ref RCC_HSE_Config
  uint32_t HSEPredivValue;        // HSE预分频值      @ref RCCEx_Prediv1_Factor
  uint32_t LSEState;              // LSE状态          @ref RCC_LSE_Config
  uint32_t HSIState;              // HSI状态            @ref RCC_HSI_Config
  uint32_t HSICalibrationValue;   // HSI校准调整值  Min_Data = 0x00 and Max_Data = 0x1F 
  uint32_t LSIState;              // LSI状态             @ref RCC_LSI_Config 
  RCC_PLLInitTypeDef PLL;         // RCC-PLL锁相环结构体-可配置锁相环开关、时钟来源、倍数
} RCC_OscInitTypeDef;   //设置系统各时钟的来源,选项见stm32f1xx_hal_rcc.h
  uint32_t ClockType;             // 选择将被配置的时钟@ref RCC_System_Clock_Type 
  uint32_t SYSCLKSource;          // 系统时钟来源     @ref RCC_System_Clock_Source 
  uint32_t AHBCLKDivider;         // AHB时钟分频@ref RCC_AHB_Clock_Source 
  uint32_t APB1CLKDivider;        // APB1时钟分频@ref RCC_APB1_APB2_Clock_Source 
  uint32_t APB2CLKDivider;        // APB2时钟分频@ref RCC_APB1_APB2_Clock_Source 
} RCC_ClkInitTypeDef;   //设置AHB和APB总线时钟配置*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

当我们开始使用其他外设时,应对外设进行初始化

验证裸机

我们在完成初始化代码之后,应当验证一下裸机代码能否在板子上运行,这里使用一个LED闪烁验证
LED硬件连接
1.创建GPIO初始化函数
2.新建一个GPIO初始化结构体。
3.开启对应的时钟
3.修改GPIO结构体内容
4.配置GPIO初始化。
5.使用GPIO进行控制闪烁

移植RTOS

目前,我们初步完成了启动文件、系统时钟配置工作,然后尝试移植RTOS

见:https://blog.csdn.net/u012376741/article/details/127081582?spm=1001.2014.3001.5502
或:https://gitee.com/jixukong/rt-thread-nano

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/67463
推荐阅读
相关标签
  

闽ICP备14008679号