Run Micro-ROS on almost any stm32

2023-12-07 11:36
文章标签 stm32 ros run micro almost

本文主要是介绍Run Micro-ROS on almost any stm32,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 Run Micro-ROS on almost any stm32 - Tech blog (guillaumebeuzeboc.github.io)

Run Micro-ROS on almost any stm32

19 Sep 2021 » c, cmake, stm32, micro-ros, clion

如果用的不是STM32F4,需要自己去生成micro_ros_stm32cubemx_utils库

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 GitHub - micro-ROS/micro_ros_setup at 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 GitHub - micro-ROS/micro_ros_stm32cubemx_utils at foxy. For this example, this repo as well as the CubeMX project are going to be located in one directory.

.
├── l476rg_test   # The CubeMX project explained right after
└── micro_ros_stm32cubemx_utils # the repo

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.

UART2 setup

I left the default basic setup of it (115200 Bits/s, 8 Bits, None, 1). Check the “Global interrupt” checkbox under the NVIC Settings.

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).

DMA setup

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).

FreeRTOS setup

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).

FreeRTOS task setup

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:

@@ -10,7 +10,7 @@ if [ -f "$BASE_PATH/libmicroros/libmicroros.a" ]; thenexit 0fi######## Trying to retrieve CFLAGS ########
-export RET_CFLAGS=$(find /project -type f -name *.mk -exec cat {} \; | python3 $BASE_PATH/library_generation/extract_flags.py)
+export RET_CFLAGS=$(find /project -type f -name *.m[a]k[e] -exec cat {} \; | python3 $BASE_PATH/library_generation/extract_flags.py)RET_CODE=$?if [ $RET_CODE = "0" ]; then

Once it’s done, from the directory containing the CubeMX project and the micro_ros_stm32cubemx_utils repo, launch

 docker pull microros/micro_ros_static_library_builder:foxy &&\docker run --rm -v ${PWD}:/project --env MICROROS_LIBRARY_FOLDER=micro_ros_stm32cubemx_utils/microros_static_library_ide microros/micro_ros_static_library_builder:foxy`

You should see the list of CFLAGS detected. In my case:

 Found CFLAGS:
-------------
-ffunction-sections -fdata-sections -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Og
-------------

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:

include_directories(Core/IncDrivers/STM32L4xx_HAL_Driver/IncDrivers/STM32L4xx_HAL_Driver/Inc/LegacyMiddlewares/Third_Party/FreeRTOS/Source/includeMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4FDrivers/CMSIS/Device/ST/STM32L4xx/Include Drivers/CMSIS/Includelibmicroros/include)

We also need to add the Micro-ROS extra_sources to the source file glob:

file(GLOB_RECURSE SOURCES "startup/*.*" "Middlewares/*.*" "Drivers/*.*" "Core/*.*" "libmicroros/extra_sources/*.*")

And finally we need to link the Micro-ROS static library to our target

target_link_libraries(${PROJECT_NAME}.elf ${CMAKE_SOURCE_DIR}/libmicroros/libmicroros.a)
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.

/* USER CODE BEGIN Includes */
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <uxr/client/transport.h>
#include <rmw_microros/rmw_microros.h>
#include <rcutils/stdatomic_helper/gcc/stdatomic.h>#include <std_msgs/msg/int32.h>
/* USER CODE END Includes */

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)

/* USER CODE BEGIN 4 */
bool cubemx_transport_open(struct uxrCustomTransport * transport);
bool cubemx_transport_close(struct uxrCustomTransport * transport);
size_t cubemx_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
size_t cubemx_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);void * microros_allocate(size_t size, void * state);
void microros_deallocate(void * pointer, void * state);
void * microros_reallocate(void * pointer, size_t size, void * state);
void * microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void * state);
/* USER CODE END 4 */

Then we are going to change the code directly in our StartDefaultTask.

void StartDefaultTask(void *argument)
{/* USER CODE BEGIN 5 *//* Here we give our huart2 interface, and the 4 * transport functions*/rmw_uros_set_custom_transport(true,(void *) &huart2,cubemx_transport_open,cubemx_transport_close,cubemx_transport_write,cubemx_transport_read);/* Here you also give to the allocator the functions* that are going to be used in order to allocate memory etc.*/rcl_allocator_t freeRTOS_allocator = rcutils_get_zero_initialized_allocator();freeRTOS_allocator.allocate = microros_allocate;freeRTOS_allocator.deallocate = microros_deallocate;freeRTOS_allocator.reallocate = microros_reallocate;freeRTOS_allocator.zero_allocate =  microros_zero_allocate;if (!rcutils_set_default_allocator(&freeRTOS_allocator)) {printf("Error on default allocators (line %d)\n", __LINE__);}// Micro-ROS apprcl_publisher_t publisher;std_msgs__msg__Int32 msg;/* The support is the structure that is going to carry all* the information about your Micro-ROS instance * (context, allocator, clock , options)*/rclc_support_t support;// The allocator that we defined earlierrcl_allocator_t allocator;rcl_node_t node;allocator = rcl_get_default_allocator();//create init_optionsrclc_support_init(&support, 0, NULL, &allocator);// create noderclc_node_init_default(&node, "cubemx_node", "", &support);// create publisherrclc_publisher_init_default(&publisher,&node,ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),"cubemx_publisher");msg.data = 0;for(;;){rcl_ret_t ret = rcl_publish(&publisher, &msg, NULL);if (ret != RCL_RET_OK){printf("Error publishing (line %d)\n", __LINE__);NVIC_SystemReset(); // If we cannot publish we restart}msg.data++;osDelay(10);}/* USER CODE END 5 */
}

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:

[1632668621.125343] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1632668621.125450] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 4
[1632668621.126870] info     | Root.cpp           | create_client            | create                 | client_key: 0x5851F42D, session_id: 0x81
[1632668621.126911] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x5851F42D, address: 0
[1632668621.142403] info     | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x5851F42D, participant_id: 0x000(1)
[1632668621.157779] info     | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x5851F42D, topic_id: 0x000(2), participant_id: 0x000(1)
[1632668621.166655] info     | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x5851F42D, publisher_id: 0x000(3), participant_id: 0x000(1)
[1632668621.176929] info     | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x5851F42D, datawriter_id: 0x000(5), publisher_id: 0x000(3)

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.

:: ~ » ros2 topic echo /cubemx_publisher
data: 123
---
data: 124
---
.
.
.

You can find the complete example here: GitHub - Guillaumebeuzeboc/Micro-ROS-stm32-basic-pub

If you have any suggestion/question/remark please don’t hesitate to leave a comment.

Share this on →  Tweet 

这篇关于Run Micro-ROS on almost any stm32的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/465709

相关文章

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu

ROS - C++实现RosBag包回放/提取

文章目录 1. 回放原理2. 回放/提取 多个话题3. 回放/提取数据包,并实时发布 1. 回放原理 #include <ros/ros.h>#include <rosbag/bag.h>#include <std_msgs/String.h>int main(int argc, char** argv){// 初始化ROS节点ros::init(argc, argv,

ROS - C++实现RosBag包录制

文章目录 1. 录制原理2. 录制多个话题3. 订阅ROS消息,实时录制 1. 录制原理 #include <ros/ros.h>#include <rosbag/bag.h>#include <std_msgs/String.h>int main(int argc, char** argv){// 初始化ROS节点ros::init(argc, argv, "reco

hector_quadrotor编译总结 | ubuntu 16.04 ros-kinetic版本

hector_quadrotor编译总结 | ubuntu 16.04 ros-kinetic版本 基于Ubuntu 16.04 LTS系统所用ROS版本为 Kinetic hector_quadrotor ROS包主要用于四旋翼无人机的建模、控制和仿真。 1.安装依赖库 所需系统及依赖库 Ubuntu 16.04|ros-kinetic|Gazebo|gazebo_ros_pkgs|ge

hector_quadrotor编译总结 | ubuntu 14.04 ros-indigo版本

hector_quadrotor编译总结 | ubuntu 14.04 ros-indigo版本 基于Ubuntu 14.04 LTS系统所用ROS版本为 Indigo hector_quadrotor ROS包主要用于四旋翼无人机的建模、控制和仿真。 备注:两种安装方式可选:install the binary packages | install the source files