ubuntu16.04上搭建stm32f4开发环境
搭建交叉编译环境
stm32 属于arm cortex-m系列thumb指令集,使用的编译工具是arm-none-eabi,不同的内核的板子都是不一样的.在下面的地址可以下载到:
https://launchpad.net/gcc-arm-embedded/+download
在电脑目录上解压,并在使用的到的bash配置文件下,设置相应的路径环境变量,比如我使用的是zsh就在相应的~/.zshrc里面加上:
export PATH=$PATH:/home/raoxu/tool/gcc-arm-none-eabi-5_4-2016q3/bin
任意目录下测试是否可以使用
arm-none-eabi-gcc -v
编写makefile
我的工程目录
├── \
├── include
│ ├── stm32f4xx_hal_conf.h
│ └── stm32f4xx_hal.h
├── lib
│ ├── libapp.a
│ └── libstm32.a
├── makefile
├── makefile.common
├── STM32Cube_FW_F4_V1.10.0
│ ├── Documentation
│ ├── Drivers
│ ├── _htmresc
│ ├── Makefile
│ ├── Middlewares
│ ├── package.xml
│ ├── Projects
│ ├── Release_Notes.html
│ ├── tags
│ └── Utilities
├── STM32F407VGTx_FLASH.ld
├── tags
└── user
├── app.a
├── main.c
├── main.h
├── makefile
├── startup_stm32f407xx.s
├── stm32f4xx_it.c
├── stm32f4xx_it.h
└── system_stm32f4xx.c
先看根目录下的makefile.common这里是几个目录下公用的
TOP = $(shell pwd)
PROGRAM = stm32f4_out
LIBDIR = $(TOP)/lib
TypeOfMCU=STM32F407xx
TC=arm-none-eabi
CC=$(TC)-gcc
LD=$(TC)-ld -v
OBJCOPY=$(TC)-objcopy
AR=$(TC)-ar
GDB=$(TC)-gdb
INCLUDE=-I$(TOP)/include
COMMONFLAGS=-g -mcpu=cortex-m3 -mthumb
COMMONFLAGSlib=$(COMMONFLAGS)
CFLAGS+=$(COMMONFLAGS) -Wall -Werror $(INCLUDE)
CFLAGS+=-D $(TypeOfMCU)
CFLAGS+=-D VECT_TAB_FLASH
CFLAGSlib+=$(COMMONFLAGSlib) -Wall -Werror $(INCLUDE)
CFLAGSlib+=-D $(TypeOfMCU)
CFLAGSlib+=-D VECT_TAB_FLASH
编译stm32的hal库,静态库
- 接下来就是编译stm32的hal库的makefile,这是第一个版本有点粗糙,后面或不定期更新
# libs Makefile
include ../makefile.common
CFLAGSlib+=-c
STM32LIB = $(shell pwd)
obj1 = $(STM32LIB)/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/*.o
obj2 = $(STM32LIB)/Drivers/STM32F4xx_HAL_Driver/Src/*.o
inc1 = $(STM32LIB)/Drivers/STM32F4xx_HAL_STM32LIB/Inc
inc2 = $(STM32LIB)/Drivers/CMSIS/Device/ST/STM32F4xx/Include/
inc3 = $(STM32LIB)/Drivers/CMSIS/Include
inc4 = $(STM32LIB)/Drivers/STM32F4xx_HAL_Driver/Inc
libstm32.a: $(obj1) $(obj2)
echo "comlile stm32lib.a"
$(AR) cr $(STM32LIB)/Drivers/$@ $^
echo "make stm32lib success"
$(obj1) :
echo "comlile obj1"
cd $(STM32LIB)/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/ && \
$(CC) $(CFLAGSlib) \
-I$(inc1) -I$(inc2) -I$(inc3) \
system_stm32f4xx.c
$(obj2) :
echo "comlile obj2"
cd $(STM32LIB)/Drivers/STM32F4xx_HAL_Driver/Src && \
$(CC) $(CFLAGSlib) \
-I$(inc4) -I$(inc2) -I$(inc3) \
-I../../../../include \
*.c
.PHONY: clean
clean:
rm -f $(STM32LIB)/Drivers/libstm32.a $(obj1) $(obj2)
编译的结果:
make clean;make
rm -f /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/libstm32.a /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/*.o /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Src/*.o
echo "comlile obj1"
comlile obj1
cd /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/ && \
arm-none-eabi-gcc -g -mcpu=cortex-m3 -mthumb -Wall -Werror -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/include -D STM32F407xx -D VECT_TAB_FLASH -c \
-I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_STM32LIB/Inc -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include/ -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Include \
system_stm32f4xx.c
echo "comlile obj2"
comlile obj2
cd /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Src && \
arm-none-eabi-gcc -g -mcpu=cortex-m3 -mthumb -Wall -Werror -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/include -D STM32F407xx -D VECT_TAB_FLASH -c \
-I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Inc -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include/ -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Include \
-I../../../../include \
*.c
echo "comlile stm32lib.a"
comlile stm32lib.a
arm-none-eabi-ar cr /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/libstm32.a /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/*.o /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Src/*.o
echo "make stm32lib success"
make stm32lib success
可以找到./STM32Cube_FW_F4_V1.10.0/Drivers/libstm32.a这样静态库就编译成功了
编译用户程序,静态库
- 简单的main.c
写了一个简单的点灯程序,查询按键点灯
/* Configure the GPIO_LED pin */
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* Infinite loop */
while (1)
{
if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4) == 1) {
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, SET);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, SET);
} else {
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, RESET);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, RESET);
}
}
我是用的是正点原子的板子,按键pe4就会点亮pf9和pf10,之后下载程序后可以单步调试,看效果
接下来是user目录下的makefile
include ../makefile.common
CFLAGSlib+=-c
USER = $(shell pwd)
src += ./*.c
src += ./*.s
obj = ./*.o
.PHONY :obj
libapp.a : $(obj)
$(AR) cr $@ \
$^
$(obj):
$(CC) $(CFLAGSlib) \
-I../include \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Inc \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Include \
$(src)
.PHONY :clean
clean :
rm libapp.a $(obj)
make clean;make 之后
rm libapp.a ./*.o
rm: cannot remove 'libapp.a': No such file or directory
rm: cannot remove './*.o': No such file or directory
makefile:25: recipe for target 'clean' failed
make: *** [clean] Error 1
arm-none-eabi-gcc -g -mcpu=cortex-m3 -mthumb -Wall -Werror -I/home/raoxu/self_education/stm32_project/user/include -D STM32F407xx -D VECT_TAB_FLASH -c \
-I../include \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Inc \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Include \
./*.c ./*.s
arm-none-eabi-ar cr libapp.a \
*.o
可以看到user目录下生成了libapp.a的静态库
boot文件,以及链接脚本
boot文件使用hal库里自带的汇编文件(启动文件)
链接脚本使用的是hal库在带的链接脚本
注意的是不同的芯片都需要使用不同的boot文件和链接脚本
编译链接可执行文件
根目录下的makefile
# general Makefile
include makefile.common
LDFLAGS=$(COMMONFLAGS) -fno-exceptions -ffunction-sections -fdata-sections -L$(LIBDIR) -nostartfiles -Wl,--gc-sections,-TSTM32F407VGTx_FLASH.ld
LDLIBS+=-lstm32
LDLIBS+=-lapp
all: user STM32Cube_FW_F4_V1.10.0
$(CC) -o $(PROGRAM).elf $(LDFLAGS) \
-Wl,--whole-archive \
user/libapp.a \
-Wl,--no-whole-archive \
$(LDLIBS)
$(OBJCOPY) -O ihex $(PROGRAM).elf $(PROGRAM).hex
$(OBJCOPY) -O binary $(PROGRAM).elf $(PROGRAM).bin
#Extract info contained in ELF to readable text-files:
arm-none-eabi-readelf -a $(PROGRAM).elf > $(PROGRAM).info_elf
arm-none-eabi-size -d -B -t $(PROGRAM).elf > $(PROGRAM).info_size
arm-none-eabi-objdump -S $(PROGRAM).elf > $(PROGRAM).info_code
arm-none-eabi-nm -t d -S --size-sort -s $(PROGRAM).elf > $(PROGRAM).info_symbol
STM32Cube_FW_F4_V1.10.0:
$(MAKE) -C STM32Cube_FW_F4_V1.10.0 $@
user:
$(MAKE) -C user $@
.PHONY: clean
# 总控的makefile使用$(MAKE)这个宏调用,子目录下的makefile
# 这里的意思是先进入-C之后的目录中然后执行该目录下的makefile
clean:
rm $(PROGRAM).*
将两个静态库拷贝到lib目录下面去,make clean;make 运行的结果是:
rm stm32f4_out.*
rm: cannot remove 'stm32f4_out.*': No such file or directory
makefile:34: recipe for target 'clean' failed
make: *** [clean] Error 1
arm-none-eabi-gcc -o stm32f4_out.elf -g -mcpu=cortex-m3 -mthumb -fno-exceptions -ffunction-sections -fdata-sections -L/home/raoxu/self_education/stm32_project/lib -nostartfiles -Wl,--gc-sections,-TSTM32F407VGTx_FLASH.ld \
-Wl,--whole-archive \
user/libapp.a \
-Wl,--no-whole-archive \
-lstm32 -lapp
arm-none-eabi-objcopy -O ihex stm32f4_out.elf stm32f4_out.hex
arm-none-eabi-objcopy -O binary stm32f4_out.elf stm32f4_out.bin
#Extract info contained in ELF to readable text-files:
arm-none-eabi-readelf -a stm32f4_out.elf > stm32f4_out.info_elf
arm-none-eabi-size -d -B -t stm32f4_out.elf > stm32f4_out.info_size
arm-none-eabi-objdump -S stm32f4_out.elf > stm32f4_out.info_code
arm-none-eabi-nm -t d -S --size-sort -s stm32f4_out.elf > stm32f4_out.info_symbol
这样就算成功了,elf文件和bin文件都有了.但是过程比较麻烦,之后我会写个脚本,简化工作.接下来搭建,下载调试的环境
搭建基于stlink opencd的,下载代码及gdb调试环境
安装stlink
1.安装libusb
sudo apt-get install libusb-dev
使用源码安装:
地址:
安装openocd
使用命令安装就可以了
sudo apt-get install openocd
下载程序
- 运行openocd的命令连上板子
openocd -f interface/stlink-v2.cfg -f target/stm32f4x_stlink.cfg
(ps:类似的命令,我使用jlink发现不能使用,只能支持f1的单片机,f4的板子无法使用) - 通过