Micro-ROS brings the ability to integrate microcontrollers into the ROS ecosystem. Having microcontrollers publishing topic directly into your ROS2 host could facilitate a lot of the integration. So far, Micro-ROS is only officially supporting a small amount of boards. Unfortunately, I didn’t have any stm32 board officially supported by Micro-ROS, so I decided to have a look at how to run Micro-ROS on the stm32 board I had at home. So I have a Nucleo-L476RG which is an ultra low power board. It has a lot of pins and configuration possibility, a Flash size of 1 MB and two RAMs (96 KB and 32 KB). In my case, I am going to use the UART to transmit my data (using the debugger UART to avoid additional wiring). Basically what we are going to do is that we are going to create a project with CUBEMX, configure it and adapt the CMakeLists in order to link with the static Micro-ROS library. In my case I will use Clion as an IDE but most of the CMake-compatible IDE should work (Clion has a nice stm32 plugins that facilitates a lot of things like uploading, debugging, etc.). Micro-ROS is not already expecting you to use CMake, it’s rather using plain Makefiles. But with just a few changes we will be able to use Cmake.
Install all you need
In this post, I am using Ubuntu 20.04 with ROS2 foxy already installed.
Micro ROS setup
Clone this repo https://github.com/micro-ROS/micro_ros_setup/tree/foxy and follow the instruction in order to build the Micro-ROS agent (interface between the UART and ROS2).
Micro_ros_stm32cubemx_utils
In order to generate the static library, we are going to need another repo micro_ros_stm32cubemx_utils https://github.com/micro-ROS/micro_ros_stm32cubemx_utils/tree/foxy. For this example, this repo as well as the CubeMX project are going to be located in one directory.
Generate your project with CubeMX
UART
Within CubeMX I generated a project for my board: Nucleo-476RG. I activate the USART2 (the one connected to the debugger). Configure it for asynchronous and disable hardware control.
I left the default basic setup of it (115200 Bits/s, 8 Bits, None, 1). Check the “Global interrupt” checkbox under the NVIC Settings.
Make sure to enable to DMA for the corresponding UART. Both priorities must be set to very hight and RX direction must be set to Peripheral To Memory and TX one to Memory to Peripheral. Please also make sure that RX DMA Request settings Mode is set to Circular (Keep the Normal on for TX).
FreeRTOS
For our example, we will need FreeRTOS. We will simply need to configure a task (the default) for Micro-ROS. Activate FreeRTOS in CubeMX (I used CMSIS v2). Micro-ros will need at least 12 kB for its task, hence we need to increase the default TOTAL_HEAP_SIZE of FreeRTOS. I picked 20000 bytes for my test (but you can of course use 12000).
You must also create a task for your Micro-ROS. We are simply going to use the default one. And set a size of 3000 words (3000 words of 4 bytes is 12 kB).
Generate the project
Here I want to use Clion with Cmake hence I am going to generate my project for the SW4STM32 toolchain : Project Manage -> Project -> Toolchain / IDE; and select SW4STM32. Generate code in order to have the source files as well as the CMakeLists.txt.
Generate the Micro-ROS static library
Here we are going to use the micro_ros_stm32cubemx_utils repo that we downloaded before. This repository is using the Makefiles to extract the compilation flags in order to build the Micro-ROS static library. Unfortunately, so far it’s only extracting from files with .mk extension and in our case the file containing the flags (generated by Cmake) is called flags.make
. Thus, we will have to make a little change to the repo. We will change the file microros_static_library_ide/library_generation/library_generation.sh by adding [a]
and [e]
line 13:
Once it’s done, from the directory containing the CubeMX project and the micro_ros_stm32cubemx_utils repo, launch
You should see the list of CFLAGS detected. In my case:
Make sure the options are the same that are on for your target, otherwise you could face some undefined var/functions or linking issues. This will take some time and after in the subfolder “libmicroros” containing an “include” folder and the library. In my case, I copied the libmicroros folder in my stm32 project root. I also included in it the extra_sources available in the “micro_ros_stm32cubemx_utils” repo.
Use the library
CMakeLists.txt
In order to use the library, we must add it and the headers in our CMakeLists.txt. We must first add the includes from Micro-ROS:
We also need to add the Micro-ROS extra_sources to the source file glob:
And finally we need to link the Micro-ROS static library to our target
Updating the main.c
Now that the CMakeLists.txt is ready, we can modify the main in order to publish our topic. We are basically going to use what is defined in https://github.com/micro-ROS/micro_ros_stm32cubemx_utils/blob/foxy/sample_main.c which is a full example of topic publishing. We will only have to modify the main.c (core/src) in our case.
First, we must include the necessary Micro-ROS layer includes, and our message type.
We need to declare a bunch of methods that are actually defined in the extra_sources files (in our case in dma_transport.c and in microros_allocators.c)
Then we are going to change the code directly in our StartDefaultTask.
From this point, your code is ready to compile and ready to upload on the MCU. On my MCU compiled with debug mode, the publisher takes one to two second to start publishing. Once your MCU is running and connected to your computer, you will need the Micro-ROS agent. Make sure to source your Micro-ROS ws source microros_ws/install/local_setup.zsh
and run the agent ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0
(To identify your serial port, you can simply list your /dev/ and check which one appears when you connect your MCU). Your agent should display something like:
Here we see that a node connects and that it create a publisher. Now your MCU topic is available in your ROS2 and you can simply echo it.
You can find the complete example here: https://github.com/Guillaumebeuzeboc/Micro-ROS-stm32-basic-pub
If you have any suggestion/question/remark please don’t hesitate to leave a comment.