基于STM32 HAL库在Makefile+GCC-ARM上面的工程编译

之所以用这种方式开发,是因为当下MDK编译的速度实在是太慢了,可能是因为PC是祖传的问题吧。而且个人认为

这样可以多了解GCC-ARM的工具以及Makefile,为后续学习u-boot打基础。这种方式适合喜欢旁门左道的道友去学

习,而且网上基本找不到关于这种开发模式的文章,写下这个也是为了以后万一以后记不住可以翻出来看看。同时很

感谢一些大佬的耐心指导。回归正题。

一、首先是工具及材料的准备

1、一个能在MDK下编译通过的工程,这里要说明的是启动文件不能用“ARMCC”文件夹下的,需要使用“GCC”文件夹

下的,其他的照搬过来;

2、GCC交叉编译工具链,因为一开始是考虑在window环境下进行编译的,所以在GUN官网下了个win平台的工具

链,下载后直接安装,记住安装位置,安装好之后,需要设置控制台的环境变量,这里贴出DOS的环境变量设置,对

于linux平台下的道友请自行百度:

(1)打开我的电脑的属性,因为本人是win10,窗口略有不同,点击“高级系统设置”;


(2)然后点击“环境变量”;


(3)、然后在系统变量里面找到“path”的环境变量,双击它进入编辑,或者选中它然后点“编辑”,因为设置了几个变

量值,所以会弹出第四步的管理窗口,如果变量值少,是不会弹出窗口的,只能在当前窗口设置的;


(4)接下来就是添加变量值了,在GCC的安装目录下会有一个“bin”目录,里面就是GCC工具链包含的所有能用的工

具了,把这个目录的绝对路径添加到这个环境变量中,然后保存就可以了;


(5)接下来就是测试是否安装成功了,打开控制台,输入“arm-none-eabi-gcc -v”,显示如下内容就表示安装成功

了;


3、接下来是make工具,在win下,如果你安装了VC工具的话,就不用下载make工具了,直接把安装VC目录里面

的“VC/bin”目录添加到刚才说的环境变量中去,如图4所指的下一个变量值,然后在控制台里输入“nmake -v”,如果显

示如下图内容,就表示make工具可以用,因为win下的make命令与linux下不同,这个要注意。Linux下默认是有make

工具的,所以这步可以跳过。


二、工具测试

在安装目录下有个“share”文件夹,里面包含两个内容,一个是GNU官方提供的一些demo,而且已经写好了

Makefile,只需要Make 一下就能生成文件了;另一个是关于GCC工具链所有工具的PDF介绍,里面很详细的介绍了

这些工具以及工具参数的使用,虽然只是英文的,但还是能提供一些帮助。

         1、直接进入到一个demo的目录下,执行make,出现以下内容,就表示可以使用了,箭头指示的地方是本人把

目录名字改过了,后面的目录名都没有变的;


  2、这时在demo的目录下会生成一个“.map”文件以及“.axf”文件,说明一切成功,这里还有一点说明的是,在win平台

下,make工具与linux的有差异,在执行上步的时候会提示如下故障:


这时打开这个Makefile文件,修改成如下的内容就可以了:


三、直接编译

上面说了这么多废话,都是在磨刀,现在才是正式砍柴了。

         1、因为之前没有深入了解过Makefile的规则语法,所以先跳过Makefile,直接用GCC工具链编译工程看看,如

下图:


(1)、首先红色线的表示工具;
(2)、紧跟着黄色线是我这个工程需要包含的头文件目录,就像MDK项目设置头文件一样,只不过这里用的是相对
路径;
(3)、然后是绿色线的表示ARM内核的架构,关于这个参数可以在GCC文档目录的“readme.txt”文本里面找到;
(4)、再然后是工程的.c以及.s文件,我是先把要用的库文件都放在一个目录下,这样方便测试用;
(5)、最后是三个参数,“-o main.out”是生成指定的目标文件名,你可以指定任意名字;“-Wl,--gc-sections”这个参
数至关重要,它是链接所有文件时要用的,本人就是被这个参数搞了一天时间;最后的“-T STM32F103XE_FLASH.ld”这个链接脚本是ST官方提供的,它在启动文件“gcc\linker”目录下,找到自己对应的链接脚
本拷过来就可以了;

2、如出现上图,没什么警告的话,就会编译出“main.out”这个文件了。假如出现说未找到如下图的文件,则可以打开

链接文件,把这部分内容屏蔽掉就可以了:


3、接下来就是转变成可以下载的二进制文件了,如下图,转成“.bin”的文件,下载的时候需要指定一下地址:


关于上面的编译方法,贫道墙裂推荐去看看《Cortex-M3权威指南(中文)》这本书,即使是中文版的,里面也很详细的

描述了关于GUN编译的过程,这本书是学习STM32F1系列芯片必看的一本书,找不到这本书的可以找我要,我会在

后面附上联系方式。

四、Make file编译

下面是Makefile的部分了,介绍Makefile之前,贫道再向道友推荐一本书,叫《GNU make中文手册》,这里非常详

细的说明了Makefile的语法规则以及怎么执行的内容,同样各位道友找不到此书可以找贫道要。此书在linux用是没问

题的,在win平台下很多语法不能用,毕竟window的尿性,你懂的。

1、首先我是用两个配置文件加一个Makefile文件进行搭配的,先来看编译配置文件的代码,里面包括了,你选用的内

核、编译工具(因为GCC有几个工具)以及编译的选项(像代码优化这些的参数,具体可以去看刚刚说的工具链的

PDF):

# Selecting Core
ARM_CORE=cortex-m3

# Compiler & Linker command
CC=arm-none-eabi-gcc
AS=arm-none-eabi-as
AR=arm-none-eabi-ar
LD=arm-none-eabi-ld
OBJCOPY=arm-none-eabi-objcopy

# Options for specific architecture
ARCH_OPTION=-mthumb -mcpu=$(ARM_CORE)

# -Os -flto -ffunction-sections -fdata-sections to compile for code size
#CODE_OPTION:=-Os -flto -ffunction-sections -fdata-sections
CODE_OPTION=-Os -ffunction-sections -fdata-sections

# Link for code size
LINK_OPTION=-Wl,--gc-sections

# Use newlib-nano. To disable it, specify USE_NANO=
#USE_NANO_OPTION:=--specs=nano.specs

# Use seimhosting or not
#USE_SEMIHOST_OPTION:=--specs=rdimon.specs
#USE_NOHOST_OPTION:=--specs=nosys.specs

# Create map file
#MAP_OPTION:=-Wl,-Map=$(NAME).map

################################################################
# Option
C_OBJECT_OPTION=$(ARCH_OPTION) $(CODE_OPTION) -c
S_OBJECT_OPTION=$(ARCH_OPTION)
LINK_OPTION=$(ARCH_OPTION) $(CODE_OPTION) $(LINK_OPTION)
HEX_OPTION=-O ihex
BIN_OPTION=-O binary

2、再来是工程配置文件的代码,里面包括的你要生成的目标名称、工程路径、目标文件的存放路径、头文件路径、
链接文件、启动文件以及源文件。注意这些带有文件的都需要指明路径,因为DOS的make我没找到目录搜寻的方法
,与linux的区别很大,看代码:
# Target name
TARGET_NAME=nrf

# Building files path
BUILD_PATH=./

# Object files path
OBJECT_PATH=$(BUILD_PATH)Obj/

# Header files path
HEAD_PATH=-I./_USER \
			-I./_HAL/Inc \
			-I./_CMSIS/Include \
			-I./_CMSIS/Device/Include
#HEAD_PATH+=

# Link file name and path
LINK_NAME_PATH=$(BUILD_PATH)_CMSIS/Device/Source/gcc/linker/STM32F103XE_FLASH.ld

# Start file name and path
#START_NAME_PATH:=startup_stm32f103x6.s
#START_NAME_PATH:=startup_stm32f103xb.s
START_NAME_PATH=$(BUILD_PATH)_CMSIS/Device/Source/gcc/startup_stm32f103xe.s
#START_NAME_PATH:=startup_stm32f103xg.s

# Source files name and path
SOURCE_NAME_PATH=$(BUILD_PATH)_HAL/Src/stm32f1xx_hal.c \
				$(BUILD_PATH)_HAL/Src/stm32f1xx_hal_cortex.c \
				$(BUILD_PATH)_HAL/Src/stm32f1xx_hal_dma.c \
				$(BUILD_PATH)_HAL/Src/stm32f1xx_hal_gpio.c \
				$(BUILD_PATH)_HAL/Src/stm32f1xx_hal_gpio_ex.c \
				$(BUILD_PATH)_HAL/Src/stm32f1xx_hal_rcc.c \
				$(BUILD_PATH)_HAL/Src/stm32f1xx_hal_tim.c \
				$(BUILD_PATH)_HAL/Src/stm32f1xx_hal_tim_ex.c \
				$(BUILD_PATH)_CMSIS/Device/Source/system_stm32f1xx.c \
				$(BUILD_PATH)_USER/main.c \
				$(BUILD_PATH)_USER/stm32f1xx_hal_msp.c \
				$(BUILD_PATH)_USER/stm32f1xx_it.c \

#stm32f1xx_hal.c
#stm32f1xx_hal_adc.c
#stm32f1xx_hal_adc_ex.c
#stm32f1xx_hal_can.c
#stm32f1xx_hal_cec.c
#stm32f1xx_hal_cortex.c
#stm32f1xx_hal_crc.c
#stm32f1xx_hal_dac.c
#stm32f1xx_hal_dac_ex.c
#stm32f1xx_hal_eth.c
#stm32f1xx_hal_flash.c
#stm32f1xx_hal_flash_ex.c
#stm32f1xx_hal_hcd.c
#stm32f1xx_hal_i2c.c
#stm32f1xx_hal_i2s.c
#stm32f1xx_hal_irda.c
#stm32f1xx_hal_iwdg.c
#stm32f1xx_hal_msp_template.c
#stm32f1xx_hal_nand.c
#stm32f1xx_hal_nor.c
#stm32f1xx_hal_pccard.c
#stm32f1xx_hal_pcd.c
#stm32f1xx_hal_pcd_ex.c
#stm32f1xx_hal_pwr.c
#stm32f1xx_hal_rcc_ex.c
#stm32f1xx_hal_rtc.c
#stm32f1xx_hal_rtc_ex.c
#stm32f1xx_hal_sd.c
#stm32f1xx_hal_smartcard.c
#stm32f1xx_hal_spi.c
#stm32f1xx_hal_spi_ex.c
#stm32f1xx_hal_sram.c
#stm32f1xx_hal_uart.c
#stm32f1xx_hal_usart.c
#stm32f1xx_hal_wwdg.c

3、最后就是主Makefile文件了,首先包含两个配置文件,配置终极目标的依赖,因为编译成目标文件指定不了生成目
录(贫道水平有限,勿喷),所以用移动的方式处理,接下来就是目标文件的生成,最后就是用伪目标清除所有生成的文件,看代码:
include _building.conf
include _compiler.conf

all:$(TARGET_NAME).exf $(TARGET_NAME).hex $(TARGET_NAME).bin
	move /Y $(BUILD_PATH)$(TARGET_NAME).exf $(OBJECT_PATH)
	move /Y $(BUILD_PATH)$(TARGET_NAME).hex $(OBJECT_PATH)
	move /Y $(BUILD_PATH)$(TARGET_NAME).bin $(OBJECT_PATH)
	move /Y $(BUILD_PATH)*.o $(OBJECT_PATH)

$(TARGET_NAME).exf: $(START_NAME_PATH) $(SOURCE_NAME_PATH)
	$(AS) $(S_OBJECT_OPTION) $(START_NAME_PATH) -o Startup.o
	$(CC) $(C_OBJECT_OPTION) $(HEAD_PATH) $(SOURCE_NAME_PATH)
	$(CC) $(LINK_OPTION) -T$(LINK_NAME_PATH) $(BUILD_PATH)*.o -o $(TARGET_NAME).exf
	
$(TARGET_NAME).hex: $(TARGET_NAME).exf
	$(OBJCOPY) $(HEX_OPTION) $(TARGET_NAME).exf $(TARGET_NAME).hex

$(TARGET_NAME).bin: $(TARGET_NAME).exf
	$(OBJCOPY) $(BIN_OPTION) $(TARGET_NAME).exf $(TARGET_NAME).bin

clean: 
	del /q /f .\Obj\*

4、如果需要拿到linux上面用,需要更改Makefile的一些命令就可以,我都是尽量满足跨平台使用的。最后测试下使用
情况,这里直接上图了,不详细介绍:

(1)、make下,在这之前先在工程目录下新建一个“Obj”的文件夹,用来存放生成的文件。


(2)、用clean清除所有生成的文件


最后说下就是这三个文件放在工程目录下就可以了,放其他目录需要更改里面的路径就可以了。

最后附上本人的联系QQ:425356736


  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值