EEVblog Electronics Community Forum
Electronics => Microcontrollers => Topic started by: Torrentula on July 19, 2012, 11:11:22 am
-
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:
TARGET=main.hex
EXECUTABLE=main.elf
CC=arm-none-eabi-gcc
LD=arm-none-eabi-ld
#LD=arm-none-eabi-gcc
AR=arm-none-eabi-ar
AS=arm-none-eabi-as
CP=arm-none-eabi-objcopy
OD=arm-none-eabi-objdump
BIN=$(CP) -O ihex
DEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DMANGUSTA_DISCOVERY -DUSE_USB_OTG_FS -DHSE_VALUE=8000000
MCU = cortex-m4
MCFLAGS = -mcpu=$(MCU) -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=soft -mthumb-interwork -std=c99 -lm -lc
STM32_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 = -Os
CFLAGS = $(MCFLAGS) $(OPTIMIZE) $(DEFS) -I./ -I./ $(STM32_INCLUDES) -Wl,-T,stm32_flash.ld
AFLAGS = $(MCFLAGS)
#-mapcs-float use float regs. small increase in code size
STM32_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.c
SRC = 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.S
OBJDIR = .
OBJ = $(SRC:%.c=$(OBJDIR)/%.o)
OBJ += Startup.o
all: $(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
-
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.
-
Okay so here is the complete output when running make:
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 status
make: *** [main.elf] Error 1
I can't see any reason why it doesn't link to math.h
Thanks for any help!
-
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:
While the compiler is capable of generating code using the VFP ABI, no compatible runtime libraries are provided in Sourcery G++
Lite. However, VFP hard-float libraries built with both ABIs are available to Sourcery G++ Standard and Professional Edition subscribers.
If it's indeed the case, try instead the open source YAGARTO toolchain (http://www.yagarto.de/ (http://www.yagarto.de/)) or the free version of Rowley's CrossWorks.
Tony
-
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?
-
http://www.freddiechopin.info/en/download/category/6-examples (http://www.freddiechopin.info/en/download/category/6-examples)
This 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 on this link (http://www.freddiechopin.info/pl/artykuly/35-arm/59-arm-toolchain-tutorial). 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.
-
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.
-
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.
Take a look at CORDIC algorithm for atan2: http://en.wikipedia.org/wiki/CORDIC (http://en.wikipedia.org/wiki/CORDIC)
Regards,
Janne
-
Okay thanks, guys, I've managed to solve the problem.
I simply had to add -lm -lc -lnosys to the build command:
$(EXECUTABLE): $(SRC) $(STARTUP)
$(CC) $(CFLAGS) $^ -lm -lc -lnosys -o $@
This will link libm and then libc and libnosys to make sprintf() work.
Thanks again!
-
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.
-
I have used the summon-arm-toolchain script by esden to install it on my Linux machine: https://github.com/esden/summon-arm-toolchain (https://github.com/esden/summon-arm-toolchain)
It 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.html (http://www.triplespark.net/elec/pdev/arm/stm32.html)
Cheers,
Elia
-
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.html (http://www.triplespark.net/elec/pdev/arm/stm32.html)
Hey, that page has some nice tidbits. Thanks!