I am trying to use the micro_ros_stm32cubemx_utils package with my nucleo-f446re. I have followed the README and watched a youtube video and successfully compiled a basic script, but the video demonstrator uses Eclipse, and I want to use PlatformIO. This may be a question for microROS, but since it seems to work on Eclipse I figured I’d ask here first.
The microROS utils package has the user generate code from STM’s .ioc files, then provides a sample_main.c. I copied the inc/src file content to PlatformIO, built/copied the microros library, and copied the linker file. I did not add any microROS content to my inc/lib/src directories. Builds are successful until I try running the following:
status = rclc_support_init(&support, 0, NULL, &freeRTOS_allocator);
giving me the following error:
micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a(librcutils-atomic_64bits.c.obj): In function `unlock_memory':
atomic_64bits.c:(.text+0xa0): undefined reference to `__sync_synchronize'
micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a(librcutils-atomic_64bits.c.obj): In function `__atomic_load_8':
atomic_64bits.c:(.text+0x11c): undefined reference to `__sync_synchronize'
micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a(librcutils-atomic_64bits.c.obj): In function `__atomic_store_8':
atomic_64bits.c:(.text+0x198): undefined reference to `__sync_synchronize'
micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a(librcutils-atomic_64bits.c.obj): In function `__atomic_exchange_8':
atomic_64bits.c:(.text+0x214): undefined reference to `__sync_synchronize'
micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a(librcutils-atomic_64bits.c.obj): In function `__atomic_fetch_add_8':
atomic_64bits.c:(.text+0x2a8): undefined reference to `__sync_synchronize'
I’ve tried searching for __sync_synchronize in the microROS src files, but it isn’t there. There were quite a few .c files that were compiled into the library generation, but PlatformIO still seems to have trouble finding the references after linking the library in build_flags. Given that, I created a build_src_filter to include them all, but I’m worried I’m making it worse. Perhaps there’s an issue with the framework linking? At a loss on where to go from here. Thank you for the help.
platform.ini
[env:nucleo_f446re]
platform = ststm32
board = nucleo_f446re
; select linker file generated by CubeMX
board_build.ldscript = STM32F446RETx_FLASH.ld
; make build system use our HAL config file
board_build.stm32cube.custom_config_header = yes
framework = stm32cube
; lib_deps = FreeRTOS
build_flags =
-mfpu=fpv4-sp-d16
-mfloat-abi=softfp
-fno-builtin
# Includes
-I"Middlewares/Third_Party/FreeRTOS/Source/include"
-I"Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2"
-I"Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F"
-I"micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/microros_include"
-I"micro_ros_stm32cubemx_utils/extra_sources"
-I"micro_ros_stm32cubemx_utils/extra_sources/microros_transports"
# Libraries
-L"micro_ros_stm32cubemx_utils/microros_static_library/libmicroros"
-l"microros"
build_src_filter =
+<*>
+<../Middlewares/Third_Party/FreeRTOS/Source/*.c>
+<../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/*.c>
+<../Middlewares/Third_Party/FreeRTOS/Source/portable/*.c>
+<../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/*.c>
+<../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c>
+<../micro_ros_stm32cubemx_utils/extra_sources/*.c>
+<../micro_ros_stm32cubemx_utils/extra_sources/microros_transports/dma_transport.c> # change here for UDP transport
lib_archive = no
Are you sure this file needs to be compiled at all? Your MCU for sure is not 64 bits. __sync_synchronize is a function provided by the compiler for a atomic synchronization barrier. I’d try removing it from the build alltogether or chosing a NUL-implementation.
another issue suggests downgrading the compiler version
Great point, it definitely is 32-bit. I hadn’t seen either of those issues in the utils github yet, thanks for the references. I checked the colcon.meta as suggested by the first issue and I already have -DRCUTILS_NO_64_ATOMIC=ON. I can try downgrading the compiler.
Another thing I noticed, the suggestion in that first link points to the solution in the micro_ros_static_library_ide, whereas I have been using micro_ros_static_library.
Using -mfloat-abi=softfp or -mfloat-abi=hard with microros_static_library gives me an error /home/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: error: micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a(libbranch_detection_interfaces__rosidl_typesupport_c-vl53l8cx8x8__type_support.cpp.obj) uses VFP register arguments, .pio/build/nucleo_f446re/firmware.elf does not. This is similar to this post here, but I didn’t find their solutions to work.
Using either of these flags with microros_static_library_ide just ends up with the compiler being unable to find <rcl/rcl.h>. Maybe the _ide version expects rcl.h to be sourced elsewhere?
Here’s my toolchain.cmake file for the microros_static_library generation:
Unfortunately I rebuilt the micro_ros_stm32cubemx_utils package and haven’t seen the __sync_synchronize error again. This was after turning DRCUTILS_NO_64_ATOMIC=OFF and then back to DRCUTILS_NO_64_ATOMIC=ON again, as well as building microros_static_library_ide. Now, the only error I’m only seeing is the libmicroros.a uses VFP register arguements, .pio/../.elf does not.
Here’s the repo I’m working on. Cloning and building micro_ros_stm32cubemx_utils is pretty straightforward, if you’re interested in trying. You may need a sample STM32CubeMX project for the flags to work. I built this library in the MX project format, then moved it to PlatformIO.
Edit: In following the previously-referenced video, the author uses a Makefile build rather than the default STM32CubeIDE build. My Makefile knowledge is poor, but surely between this and the startup_stm32f446xx.s and STM32F446RETx_FLASH.ld files, I’m doing something incorrectly…
Edit2: changed the Makefile to build on the PlatformIO project. Still no change in the error generation. The Makefile uses -mfloat-abi=hard but using this in platform.ini generates many VFP errors.