ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

rosserial_arduino, tf and CMake-project linking error

asked 2011-11-15 12:44:48 -0600

updated 2011-11-24 05:21:58 -0600

Cmake projects for arduino does not build if TF library (or other library with floating operations: cos, sin, etc.) is used. When no math floating point operations are referenced the program build properly. Notice that the build process with ArduinoIDE works properly even with these floating points operations or TF functions references.

I get this error when I type make:

/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr5/libm.a(fp_powsodd.o):../../../libm/fplib>/fp_powsodd.S:59: relocation truncated to fit: R_AVR_13_PCREL against symbol >`__mulsf3' defined in .text section in /usr/lib/gcc/avr/4.3.5/avr5/libgcc.a(_mul_sf.o)

I've researched the problem a bit and AFAIK it is a linking error related with math functions. There is a conflict between the math functions defined on libgcc and libm. The linker flags for the TF library and also for user code should have defined the -lm flag. This lib contains mathematical functions specifically designed for AVR. If this library is not declared, the typical math functions implemented on libgcc are used (and this is the problem). I tried to fix it handling the arduino cmake scripts but no progresses until now. Maybe an expert on cmake script can do it.

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
0

answered 2011-11-30 10:23:50 -0600

Some progresses on this but a new problem appeared.

I worked with the theory that we should use -lm instead of -lgcc for floating points operations during the linking process of the elf file. The same problem can be found in the internet: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=56149&start=0

I've executed manually the final CMake linking step which fails and with can be found in "CMakeFiles/arduino_sample_name.dir/link.txt". This is what it contains:

 avr-g++    -O3 -lm -ffunction-sections -fdata-sections -fno-tree-loop-optimize -fno-move-loop-invariants       -mmcu=atmega328p CMakeFiles/hello_world_arduino.dir/src/hello_world.cpp.o CMakeFiles/hello_world_arduino.dir/src/ros_lib/time.cpp.o CMakeFiles/hello_world_arduino.dir/src/ros_lib/duration.cpp.o CMakeFiles/hello_world_arduino.dir/opt/ros/electric/stacks/rosserial/rosserial_arduino/cmake_scripts/cc_support.cpp.o  -o hello_world_arduino.elf -Wl,--as-needed -Wl,--relax -Wl,--gc-sections libatmega328_CORE.a -lm 
Here we can see the -lm as the last parameter. I added it through the CMakeList.txt command. However this does not solve the problem:
 set(${FIRMWARE_NAME}_LIBS m)
The arduino software includes a makefile "Arduino.mk" which allows to compile through the command line and with which it is possible to compile the TimeTF example. This "Arduino.mk" has an subtle difference with the ""CMakeFiles/arduino_sample_name.dir/link.txt" in the linking command: the -lm argument was included as one of the firsts arguments. Trying to mimic this behaviour I modified the rosserial_arduino/cmake_scripts/toolchains/Arduino.cmake. First I tried to modify the ARDUINO_LINKER_FLAGS without success. Finally it was possible modifiyng the CPP_FLAGS variable.
--- rosserial_arduino/cmake_scripts/toolchains/Arduino.cmake   2011-12-01 00:49:27.000000000 +0100
+++ rosserial_arduino/cmake_scripts/toolchains/Arduino.cmake2   2011-12-01 00:49:20.000000000 +0100
@@ -76,7 +76,7 @@
 # C only fine tunning
 set(TUNNING_FLAGS "-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums") 

-SET(CPP_FLAGS "-lm -ffunction-sections -fdata-sections -fno-tree-loop-optimize -fno-move-loop-invariants")
+SET(CPP_FLAGS " -ffunction-sections -fdata-sections -fno-tree-loop-optimize -fno-move-loop-invariants")

 set(CMAKE_CXX_FLAGS " -O3 ${CPP_FLAGS}")
 set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} ${TUNNING_FLAGS} -Wall -Wstrict-prototypes -std=gnu99 ${CPP_FLAGS}")

Then my "hello_world_arduino" example inspired on "TimeTF" example compiled.

 Linking CXX static library libatmega328_CORE.a
[ 76%] Built target atmega328_CORE
Scanning dependencies of target hello_world_arduino
[ 82%] Building CXX object CMakeFiles/hello_world_arduino.dir/src/hello_world.cpp.o
[ 88%] Building CXX object CMakeFiles/hello_world_arduino.dir/src/ros_lib/time.cpp.o
[ 94%] Building CXX object CMakeFiles/hello_world_arduino.dir/src/ros_lib/duration.cpp.o
[100%] Building CXX object CMakeFiles/hello_world_arduino.dir/opt/ros/electric/stacks/rosserial/rosserial_arduino/cmake_scripts/cc_support.cpp.o
Linking CXX executable hello_world_arduino.elf
[100%] Built target hello_world_arduino

Everything seemed perfect to me but in the end I got some integrity errors during the upload process:

[ 76%] Built target atmega328_CORE
[100%] Built target hello_world_arduino

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "hello_world_arduino.hex"
avrdude: writing flash (31224 bytes):

Writing | ################################################## | 100% 8.49s

avrdude: 31224 bytes of flash written
avrdude: verifying flash memory against hello_world_arduino.hex:
avrdude: load ...
(more)
edit flag offensive delete link more

Question Tools

Stats

Asked: 2011-11-15 12:44:48 -0600

Seen: 908 times

Last updated: Nov 30 '11