STM32 gcc编译环境搭建
标签(空格分隔): stm32 gcc Makefile
说在前面的话
gcc编译器兼容Windows、Linux和MAC,可自行去官网下载,此处提供参考链接:https://launchpad.net/gcc-arm-embedded/,Linux可直接在命令行输入命令:
sudo apt-get install arm-none-eabi-gcc
,自动下载安装。gcc在三大平台操作命令完全一样,下面以Linux的Ubuntu发行版为例,说明下如何为stm32搭建gcc编译环境,从此摆脱IDE~~~
本文只提供开发流程,具体技术细节不懂的欢迎在评论下留言,互相学习,或者可以自行百度~
一、安装arm gcc
- 打开命令行,输入
sudo apt-get install arm-none-eabi-gcc
- 等待安装完成,在命令行输入
arm-none-eabi-gcc -v
,出现下图所示的输出,说明安装成功
二、安装openocd
openocd用来给目标板下载程序
- 在命令行输入
sudo apt-get install openocd
- 等待安装完成,在命令行输入
openocd -v
,出现下图所示的输出,说明安装成功
三、安装jlink驱动
此处提供参考链接http://blog.csdn.net/justloong/article/details/73467875
四、修改ST的内核文件
此处以stm32f103ze为例,打开ST官方提供的内核文件STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c
,将下面两段代码中的第5行(源文件的736行)和第5行(源文件的753行)的"=r"
改为"=&r"
,变成__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
和__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
第一个代码段
uint32_t __STREXB(uint8_t value, uint8_t *addr) { uint32_t result=0; __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); return(result); }
第二个代码段
uint32_t __STREXH(uint16_t value, uint16_t *addr) { uint32_t result=0; __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); return(result); }
五、替换启动文件
stm32开发的同学都熟悉它的汇编启动文件,但是在MDk中使用的启动文件和gcc环境使用的启动文件并不相同,因为前者是arm汇编的语法,后者是gcc汇编的语法,在gcc环境下,只能使用后者,否则无法编译,而gcc下的启动文件在TM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/gcc_ride7
下,同时跟它同级目录下还有一个文件夹,叫TrueSTUDIO
,里面的启动文件是ST官方为了适配他们自己的开发环境而做的,同样可以在gcc环境中使用。
六、添加链接脚本
gcc编译需要后缀为.ld的链接脚本,里面说明了FLASH、RAM、烧录地址等信息,直接使用ST固件库里的即可,在STM32F10x_StdPeriph_Lib_V3.5.0/Project/STM32F10x_StdPeriph_Template/TrueSTUDIO
下,如下图所示:
我用的是f103ze,属于大容量,选择STM3210E-EVAL
下的stm32_flash.ld
文件,将其拷贝到自己工程根目录。TrueSTUDIO下的其他文件夹里的启动文件,都是根据不同芯片容量密度分类的,里面有readme,请阅读后,选择适合自己平台的脚本文件。
七、编写Makefile
Makefile是一种自动化的脚本,一般用来执行gcc的自动编译(当然,除此之外,它最重要的目的就是为了工程管理),关于如何编写Makefile,此处提供参考链接http://seisman.info/how-to-write-makefile.html,文档是一名叫做陈皓的工程师编写的,比较系统全面,下面粘贴出我自己工程的Makefile作为参考,实现了代码编译(make
)、目标文件清除(make clean
)和程序下载(make download
)功能,只要在工程根目录下打开命令行,输入括号中的命令即可。
#工程的名称及最后生成文件的名字
TARGET = LED
#设定临时性环境变量
export CC = arm-none-eabi-gcc
export AS = arm-none-eabi-as
export LD = arm-none-eabi-ld
export OBJCOPY = arm-none-eabi-objcopy
#读取当前工作目录
TOP=$(shell pwd)
#设定包含文件目录
INC_FLAGS= -I $(TOP)/CORE \
-I $(TOP)/HARDWARE/LED \
-I $(TOP)/STM32F10x_FWLib/inc \
-I $(TOP)/SYSTEM/delay \
-I $(TOP)/SYSTEM/sys \
-I $(TOP)/SYSTEM/usart \
-I $(TOP)/USER
CFLAGS = -W -Wall -g -mcpu=cortex-m3 -mthumb -D STM32F10X_HD -D USE_STDPERIPH_DRIVER $(INC_FLAGS) -O3 -std=gnu11
ASFLAGS = -W -Wall -g -Wall -mcpu=cortex-m3 -mthumb
C_SRC=$(shell find ./ -name '*.c')
C_OBJ=$(C_SRC:%.c=%.o)
ASM_SRC=$(shell find ./ -name '*.s')
ASM_OBJ=$(ASM_SRC:%.s=%.o)
.PHONY: all clean update
all:$(C_OBJ) $(ASM_OBJ)
$(CC) $(C_OBJ) $(ASM_OBJ) -T stm32_flash.ld -o $(TARGET).elf -mthumb -mcpu=cortex-m3 -Wl,--start-group -lc -lm -Wl,--end-group -specs=nano.specs -specs=nosys.specs -static -Wl,-cref,-u,Reset_Handler -Wl,-Map=Project.map -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80
$(OBJCOPY) $(TARGET).elf $(TARGET).bin -Obinary
$(OBJCOPY) $(TARGET).elf $(TARGET).hex -Oihex
$(C_OBJ):%.o:%.c
@$(CC) -c $(CFLAGS) -o $@ $<
$(ASM_OBJ):%.o:%.s
$(CC) -c $(ASFLAGS) -o $@ $<
clean:
rm -f $(shell find ./ -name '*.o')
rm -f $(shell find ./ -name '*.d')
rm -f $(shell find ./ -name '*.map')
rm -f $(shell find ./ -name '*.elf')
rm -f $(shell find ./ -name '*.bin')
rm -f $(shell find ./ -name '*.hex')
download:
openocd -f /usr/share/openocd/scripts/interface/jlink.cfg -f /usr/share/openocd/scripts/target/stm32f1x.cfg -c init -c halt -c "flash write_image erase $(TOP)/$(TARGET).hex" -c reset -c shutdown