AnsweredAssumed Answered

Linker Error involving VFP instructions using ARM GCC

Question asked by rks1 on Sep 4, 2015
Latest reply on Sep 11, 2015 by rks1
Here's some background on my codebase and setup:
I'm attempting to build an STM32Cube generated HAL-based project for an STM32F405xx MCU on OSX. I'm trying to do this using Makefiles and ARM GCC.
The code was generated with System Workbench as the target project. Since the makefiles generated by Eclipse are not portable, I'm using a variant of a makefile that I've used in the past. 

I've pasted my makefile and information on my compiler version and multilibs at the bottom of this post.

I have been able to successfully compile a STD Periph based project for the same MCU with a very similar makefile. In the interest of full disclosure, I should mention that I got the original version of this makefile somewhere on the internet - don't remember where anymore.

In order to generate the makefile I've pasted below, I basically took my working STD Periph makefile, and changed the include and source paths to match the new project. In order to get the correct compilation flags, I opened the project up in System Workbench and cross referenced all the flags in the Project properties window.


Here's the error I'm seeing when building:

[.../]build/stm32f4xx_hal_tim_ex.o uses VFP register arguments, [.../]binary/myElfFile.elf does not
[repeats for every src file I specify]

I understand that this has something to do with the following flags: -mfloat-abi=hard -mfpu=fpv4-sp-d16 and some incompatibilities with other libraries that are being loaded. To get a better idea of what's going on, I played around with -mfloat-abi=soft & -mfloat-abi=softfp. 

Using 'softfp' gave me a single VFP error referencing the libc file that came with gcc:
gcc-arm-none-eabi-4_8-2014q2/arm-none-eabi/lib/armv7e-m/fpu/libc_s.a(lib_a-memcpy-stub.o) uses VFP register arguments, [.../]]binary/elfkinPlatformHAL.elf does not
Using 'soft' gave me some other compile errors, but given that System Workbench compiles with hard FP and my STD Periph project compiles with my Makefile with hard FP, I'm guessing I shouldn't bother figuring whats going on there.

I'm not a makefile expert, nor am I a toolchain expert, but given that System Workbench uses GCC and Makefiles are an industry standard, I'm hoping that someone can help me understand exactly what is going on and help be build with hard FP instructions.

Heres everything you ever wanted to know about my compiler (hopefully):


> /usr/local/gcc-arm-none-eabi-4_8-2014q2/arm-none-eabi/bin/gcc -print-multi-lib
.;
thumb;@mthumb
fpu;@mfloat-abi=hard
armv6-m;@mthumb@march=armv6s-m
armv7-m;@mthumb@march=armv7-m
armv7e-m;@mthumb@march=armv7e-m
armv7-ar/thumb;@mthumb@march=armv7
armv7e-m/softfp;@mthumb@march=armv7e-m@mfloat-abi=softfp@mfpu=fpv4-sp-d16
armv7e-m/fpu;@mthumb@march=armv7e-m@mfloat-abi=hard@mfpu=fpv4-sp-d16
armv7-ar/thumb/softfp;@mthumb@march=armv7@mfloat-abi=softfp@mfpu=vfpv3-d16
armv7-ar/thumb/fpu;@mthumb@march=armv7@mfloat-abi=hard@mfpu=vfpv3-d16

> /usr/local/gcc-arm-none-eabi-4_8-2014q2/arm-none-eabi/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/usr/local/gcc-arm-none-eabi-4_8-2014q2/arm-none-eabi/bin/gcc
Target: arm-none-eabi
Configured with: /Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/src/gcc/configure --target=arm-none-eabi --prefix=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/install-native --libexecdir=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/install-native/lib --infodir=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/install-native/arm-none-eabi --build=x86_64-apple-darwin10 --host=x86_64-apple-darwin10 --with-gmp=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/build-native/host-libs/usr --with-mpfr=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/build-native/host-libs/usr --with-mpc=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/build-native/host-libs/usr --with-isl=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/build-native/host-libs/usr --with-cloog=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/build-native/host-libs/usr --with-libelf=/Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q2-20140609/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-lstdc++ -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r
Thread model: single
gcc version 4.8.4 20140526 (release) [ARM/embedded-4_8-branch revision 211358] (GNU Tools for ARM Embedded Processors) 


Here's my Makefile:
TARGET:=myElfFile
 
TOOLCHAIN_ROOT:=/usr/local/gcc-arm-none-eabi-4_8-2014q2
TOOLCHAIN_PATH:=$(TOOLCHAIN_ROOT)/bin
TOOLCHAIN_PREFIX:=arm-none-eabi
 
# Optimization level, can be [0, 1, 2, 3, s].
OPTLVL:=0
DBG:=-g
 
FREERTOS:=$(CURDIR)/Middlewares/Third_Party/FreeRTOS/Source
STARTUP:=$(CURDIR)/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc
LINKER_SCRIPT:=$(CURDIR)/Utilities/STM32F405ZGTx_FLASH.ld
 
#INCLUDE=-I$(CURDIR)/hardware
INCLUDE=-I$(CURDIR)/Inc
INCLUDE+=-I$(CURDIR)/Drivers/STM32F4xx_HAL_Driver/Inc
INCLUDE+=-I$(CURDIR)/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy
INCLUDE+=-I$(CURDIR)/Drivers/CMSIS/Include
INCLUDE+=-I$(CURDIR)/Drivers/CMSIS/Device/ST/STM32F4xx/Include
INCLUDE+=-I$(FREERTOS)/portable/GCC/ARM_CM4F
INCLUDE+=-I$(FREERTOS)/include
INCLUDE+=-I$(FREERTOS)/CMSIS_RTOS
 
 
 
BUILD_DIR = $(CURDIR)/build
BIN_DIR = $(CURDIR)/binary
 
# vpath is used so object files are written to the current directory instead
# of the same directory as their source files
vpath %.c $(CURDIR)/Drivers/STM32F4xx_HAL_Driver/Src \
      $(CURDIR)/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates $(FREERTOS) \
      $(FREERTOS)/portable/MemMang $(FREERTOS)/portable/GCC/ARM_CM4F \
      $(CURDIR)/Src $(FREERTOS)/CMSIS_RTOS
 
vpath %.s $(STARTUP)
ASRC=startup_stm32f405xx.s
 
# Project Source Files
SRC+=stm32f4xx_it.c
SRC+=system_stm32f4xx.c
SRC+=main.c
#SRC+=uart.c
#SRC+=motor.c
#SRC+=encoder.c
#SRC+=animations.c
#SRC+=syscalls.c
 
# FreeRTOS Source Files
SRC+=port.c
SRC+=list.c
SRC+=queue.c
SRC+=tasks.c
SRC+=event_groups.c
SRC+=timers.c
SRC+=heap_4.c
SRC+=cmsis_os.c
 
 
# HAL Source Files
SRC+=stm32f4xx_hal_msp.c
 
#SRC+=stm32f4xx_syscfg.c
#SRC+=misc.c
SRC+=stm32f4xx_hal.c
SRC+=stm32f4xx_hal_cortex.c
SRC+=stm32f4xx_hal_adc.c
SRC+=stm32f4xx_hal_adc_ex.c
SRC+=stm32f4xx_hal_dac.c
SRC+=stm32f4xx_hal_dac_ex.c
SRC+=stm32f4xx_hal_dma.c
#SRC+=stm32f4xx_exti.c
SRC+=stm32f4xx_hal_flash.c
SRC+=stm32f4xx_hal_flash_ex.c
SRC+=stm32f4xx_hal_gpio.c
SRC+=stm32f4xx_hal_i2c.c
SRC+=stm32f4xx_hal_i2s.c
SRC+=stm32f4xx_hal_i2s_ex.c
SRC+=stm32f4xx_hal_sd.c
SRC+=stm32f4xx_ll_sdmmc.c
SRC+=stm32f4xx_hal_rcc_ex.c
SRC+=stm32f4xx_hal_rcc.c
SRC+=stm32f4xx_hal_spi.c
SRC+=stm32f4xx_hal_tim.c
SRC+=stm32f4xx_hal_tim_ex.c
SRC+=stm32f4xx_hal_usart.c
SRC+=stm32f4xx_hal_uart.c
SRC+=stm32f4xx_hal_rng.c
 
#CDEFS=-DUSE_STDPERIPH_DRIVER
CDEFS=-DUSE_HAL_DRIVER
CDEFS+=-DSTM32F4XX
#CDEFS+=-DSTM32F405XX
CDEFS+=-DHSE_VALUE=8000000
CDEFS+=-D__FPU_PRESENT=1
CDEFS+=-D__FPU_USED=1
CDEFS+=-DARM_MATH_CM4
 
MCUFLAGS=-mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -mfpu=fpv4-sp-d16
COMMONFLAGS=-O$(OPTLVL) $(DBG) -Wall
CFLAGS=$(COMMONFLAGS) $(MCUFLAGS) $(INCLUDE) $(CDEFS)
LDLIBS=$(TOOLCHAIN_ROOT)/arm-none-eabi/lib/armv7e-m/fpu/libc_s.a $(TOOLCHAIN_ROOT)/arm-none-eabi/lib/armv7e-m/fpu/libm.a
LDFLAGS=$(COMMONFLAGS) -fno-exceptions -ffunction-sections -fdata-sections -Wl,--gc-sections,-T$(LINKER_SCRIPT) -v
 
CC=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gcc
LD=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gcc
OBJCOPY=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-objcopy
AS=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-as
AR=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-ar
GDB=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gdb
 
OBJ = $(SRC:%.c=$(BUILD_DIR)/%.o)
 
$(BUILD_DIR)/%.o: %.c
    @echo [CC] $<
    @$(CC) $(CFLAGS) $< -c -o $@
 
all: $(OBJ)
    @echo [AS] $(STARTUP)/$(ASRC)
    @$(AS) -o $(ASRC:%.s=$(BUILD_DIR)/%.o) $(STARTUP)/$(ASRC)
    @echo [LD] $(BIN_DIR)/$(TARGET).elf
    @$(CC) -o $(BIN_DIR)/$(TARGET).elf $(LDFLAGS) $(OBJ) $(ASRC:%.s=$(BUILD_DIR)/%.o) $(LDLIBS)
    @echo [OBJCOPY] $(BIN_DIR)/$(TARGET).hex
    @$(OBJCOPY) -O ihex $(BIN_DIR)/$(TARGET).elf $(BIN_DIR)/$(TARGET).hex
    @echo [OBJCOPY] $(BIN_DIR)/$(TARGET).bin
    @$(OBJCOPY) -O binary $(BIN_DIR)/$(TARGET).elf $(BIN_DIR)/$(TARGET).bin
 
.PHONY: clean
 
clean:
    @echo [RM] OBJ
    @rm -f $(OBJ)
    @rm -f $(ASRC:%.s=$(BUILD_DIR)/%.o)
    @echo [RM] BIN
    @rm -f $(BIN_DIR)/$(TARGET).elf
    @rm -f $(BIN_DIR)/$(TARGET).hex
    @rm -f $(BIN_DIR)/$(TARGET).bin
 
flash:
    @st-flash write $(BIN_DIR)/$(TARGET).bin 0x8000000

Outcomes