STM32F4 / arm-none-eabi-gcc not linking to math - Page 1
Forum section: electronics / general

author: Torrentula
author_rank: Regular Contributor
timestamp: July 19, 2012, 11:11:22 am
content: Hello guys!I started playing around with the STM32F4 Discovery. I'm using the CodeSourcery arm-none-eabi toolchain.The problem I have is when I try to use the atan2() function from math.h, the I get the error "undefined reference to atan2". It seems that the linker is not linking the executable to the math.a file and I don't know why.I tried adding -lm -lc to the compiler flags but that doesn't seem to work, the error remains.Trying to compile it with the Linaro arm-non-eabi toolchain gives me the same error + 'undefined reference to _exit'.I hope someone's able to help!Here is my Makefile:Code:TARGET=main.hexEXECUTABLE=main.elfCC=arm-none-eabi-gccLD=arm-none-eabi-ld#LD=arm-none-eabi-gccAR=arm-none-eabi-arAS=arm-none-eabi-asCP=arm-none-eabi-objcopyOD=arm-none-eabi-objdumpBIN=$(CP) -O ihexDEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DMANGUSTA_DISCOVERY -DUSE_USB_OTG_FS -DHSE_VALUE=8000000MCU = cortex-m4MCFLAGS = -mcpu=$(MCU) -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=soft -mthumb-interwork -std=c99 -lm -lcSTM32_INCLUDES = -I../../Utilities/STM32F4-Discovery \-I../../Libraries/CMSIS/ST/STM32F4xx/Include/ \-I../../Libraries/CMSIS/Include/ \-I../../Libraries/STM32F4xx_StdPeriph_Driver/inc/ \-I../../Libraries/STM32_USB_Device_Library/Class/hid/inc \-I../../Libraries/STM32_USB_Device_Library/Core/inc/ \-I../../Libraries/STM32_USB_OTG_Driver/inc/OPTIMIZE = -OsCFLAGS= $(MCFLAGS) $(OPTIMIZE) $(DEFS) -I./ -I./ $(STM32_INCLUDES) -Wl,-T,stm32_flash.ldAFLAGS= $(MCFLAGS)#-mapcs-float use float regs. small increase in code sizeSTM32_USB_OTG_SRC = ../../Libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c \../../Libraries/STM32_USB_OTG_Driver/src/usb_core.c \../../Libraries/STM32_USB_OTG_Driver/src/usb_dcd.c \STM32_USB_DEVICE_SRC = ../../Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c \../../Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c \../../Libraries/STM32_USB_Device_Library/Core/src/usbd_core.c \../../Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.cSRC = main.c \../../Utilities/STM32F4-Discovery/stm32f4xx_it.c \../../Utilities/STM32F4-Discovery/system_stm32f4xx.c \../../Utilities/STM32F4-Discovery/stm32f4_discovery.c \../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c \../../Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c \../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c \../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c \../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c \../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c \../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_i2c.c \../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c#../../Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.c \#../../Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.c \#../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c \#../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c \#../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c \#../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c \#../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dac.c \STARTUP = startup_stm32f4xx.SOBJDIR = .OBJ = $(SRC:%.c=$(OBJDIR)/%.o)OBJ += Startup.oall: $(TARGET)$(TARGET): $(EXECUTABLE)$(CP) -O ihex $^ $@$(EXECUTABLE): $(SRC) $(STARTUP)$(CC) $(CFLAGS) $^ -o $@clean:rm -f Startup.lst $(TARGET) $(TARGET).lst $(OBJ) $(AUTOGEN) $(TARGET).out $(TARGET).hex $(TARGET).map \$(TARGET).dmp $(TARGET).elf

author: nctnico
author_rank: Super Contributor
timestamp: July 19, 2012, 02:38:23 pm
content: Codesourcery comes with several libraries. The default library path is probably pointing to the wrong architecture. ld should complain about that. Try to increase the verbosity of the ld messages. It should say something about skipping the library.

author: Torrentula
author_rank: Regular Contributor
timestamp: July 19, 2012, 03:16:40 pm
content: Okay so here is the complete output when running make:Code:arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=soft -mthumb-interwork -std=c99 -lm -lc -Os -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DMANGUSTA_DISCOVERY -DUSE_USB_OTG_FS -DHSE_VALUE=8000000 -I./ -I./ -I../../Utilities/STM32F4-Discovery -I../../Libraries/CMSIS/ST/STM32F4xx/Include/ -I../../Libraries/CMSIS/Include/ -I../../Libraries/STM32F4xx_StdPeriph_Driver/inc/ -I../../Libraries/STM32_USB_Device_Library/Class/hid/inc -I../../Libraries/STM32_USB_Device_Library/Core/inc/ -I../../Libraries/STM32_USB_OTG_Driver/inc/ -Wl,-T,stm32_flash.ld main.c ../../Utilities/STM32F4-Discovery/stm32f4xx_it.c ../../Utilities/STM32F4-Discovery/system_stm32f4xx.c ../../Utilities/STM32F4-Discovery/stm32f4_discovery.c ../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c ../../Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c ../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c ../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c ../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c ../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c ../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_i2c.c ../../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c startup_stm32f4xx.S -o main.elf/tmp/ccHbXXrg.o: In function `getHeading':main.c:(.text+0x352): undefined reference to `atan2'collect2: ld returned 1 exit statusmake: *** [main.elf] Error 1I can't see any reason why it doesn't link to math.hThanks for any help!

author: kfishy
author_rank: Newbie
timestamp: July 19, 2012, 09:43:00 pm
content: Does the CodeSourcery toolchain come with floating-point standard C libraries targeting the ARMv7-M VFP?Digging around, this is what I found from the CodeSourcery user guide:QuoteIf it's indeed the case, try instead the open source YAGARTO toolchain (http://www.yagarto.de/) or the free version of Rowley's CrossWorks.Tony

author: Torrentula
author_rank: Regular Contributor
timestamp: July 20, 2012, 06:52:33 am
content: Well I have experienced the problem you mention above as well, I get an error when I try to compile with hardware floating point support.I have tried to compile the same source code with the Linaro toolchain and I get the same issue, the error message reads 'undefined reference to atan2', so it seems that the linker doesn't include the math library.HWFP doesn't give me an error though..The most info (too bad it wasn't helpful) on math being not included I found was regarding the Yagarto toolchain but I didn't find a fix for my problem there.Does anyone have a Makefile to share?

author: McMonster
author_rank: Frequent Contributor
timestamp: July 20, 2012, 12:38:52 pm
content: http://www.freddiechopin.info/en/download/category/6-examplesThis guy has examples for Eclipse/CodeSourcery/OpenOCD including makefiles and even Eclipse launch configurations. Unfortunately the very good tutorial isn't translated into English, but you may try your luck with Google Translate onthis link. He also recommends using Linaro, as it seems that it's the main toolchain supported by ARM manufacturers. One thing that's sure is that CodeSourcery does not support hardware floating point operations.

author: Torrentula
author_rank: Regular Contributor
timestamp: July 20, 2012, 02:56:28 pm
content: This guy seems to provide some other version of the math library. When looking inside the include / lib folders of the Linaro toolchain, I can see that the math lib is definitively there but the linker doesn't seem to use / find them, at least not the library file.What's a 32 bit FPU good for if I cant do any calculations other than addition, subtraction, multiplication and division?The problem is I need the atan2 function for processing data acquired by a magnetometer to calculate the heading.

author: jahonen
author_rank: Super Contributor
timestamp: July 20, 2012, 06:40:29 pm
content: Quote from: Torrentula on July 20, 2012, 02:56:28 pmTake a look at CORDIC algorithm for atan2:http://en.wikipedia.org/wiki/CORDICRegards,Janne

author: Torrentula
author_rank: Regular Contributor
timestamp: July 20, 2012, 07:38:54 pm
content: Okay thanks, guys, I've managed to solve the problem.I simply had to add -lm -lc -lnosys to the build command:Code:$(EXECUTABLE): $(SRC) $(STARTUP)$(CC) $(CFLAGS) $^ -lm -lc -lnosys -o $@This will link libm and then libc and libnosys to make sprintf() work.Thanks again!

author: mrflibble
author_rank: Super Contributor
timestamp: July 21, 2012, 11:51:53 am
content: This is with soft math right? Or did you get it to use hardware fpu?I ran into the same thing some time ago, and currently I just settle for soft. No biggie since I don't run anything high performance on it. Yet. But at some point in the future I'd love an easy to use toolchain that supports the FPU in there.Also, I'd like to reduce the number of ARM toolchains on my machine. @_@ I swear these things breed. Like rabbits.

author: Torrentula
author_rank: Regular Contributor
timestamp: July 21, 2012, 03:26:58 pm
content: I have used the summon-arm-toolchain script by esden to install it on my Linux machine:https://github.com/esden/summon-arm-toolchainIt has full hardware floating point support because it uses the Linaro GCC toolchain as opposed to other toolchains that might use CodeSourcery G++.It works quite nice until now, a little trick though is that you have to enable the FPU in your code first in order to use it, info on that can be found here:http://www.triplespark.net/elec/pdev/arm/stm32.htmlCheers,Elia

author: mrflibble
author_rank: Super Contributor
timestamp: July 21, 2012, 03:56:48 pm
content: Quote from: Torrentula on July 21, 2012, 03:26:58 pmHey, that page has some nice tidbits. Thanks!