Build stm32f4 development environment on ubuntu16.04
Build a cross-compilation environment
stm32 belongs to the arm cortex-m series thumb instruction set. The compilation tool used is arm-none-eabi. The boards of different kernels are different. It can be downloaded at the following address:
https://launchpad.net/gcc -arm-embedded/+download
Unzip on the computer directory, and set the corresponding path environment variable under the bash configuration file used. For example, if I use zsh, add it to the corresponding ~/.zshrc:
export PATH=$PATH:/home/raoxu/tool/gcc-arm-none-eabi-5_4-2016q3/bin
Test whether it can be used in any directory
arm-none-eabi-gcc -v
write makefiles
my project directory
├── \
├── 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
First look at makefile.common in the root directory. Here are the common ones in several directories.
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
Compile the hal library of stm32, static library
- The next step is to compile the makefile of the hal library of stm32. This is the first version, which is a bit rough and will be updated from time to time.
# 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)
Compiled result:
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
You can find ./STM32Cube_FW_F4_V1.10.0/Drivers/libstm32.a so that the static library is compiled successfully
Compile user program, static library
- Simple main.c
writes a simple lighting program to query button lighting
/* 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);
}
}
I am using a punctual atomic board. Press pe4 to light up pf9 and pf10. After downloading the program, you can single-step debugging to see the effect.
Next is the makefile in the user directory.
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
You can see that the static library of libapp.a is generated in the user directory
boot file, and linker script
The boot file uses the assembly file (startup file) that comes with the hal library. The
link script uses the link script that the hal library brings.
Note that different chips need to use different boot files and link scripts.
Compile link executable
makefile in the root directory
# 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).*
Copy the two static libraries to the lib directory, and the result of make clean;make is:
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
Even if this is successful, the elf file and bin file are available. But the process is more troublesome, and then I will write a script to simplify the work. Next, build and download the debugging environment
Build a stlink opencd-based, download code and gdb debugging environment
install stlink
1. Install libusb
sudo apt-get install libusb-dev
Install using source code:
Address:
install openocd
Just install it with the command
sudo apt-get install openocd
Downloader
- Run the command of openocd to connect to the board
openocd -f interface/stlink-v2.cfg -f target/stm32f4x_stlink.cfg
(ps: similar command, I found that it cannot be used using jlink, it can only support f1 MCU, f4 board cannot be used ) - pass through