非Docker环境基于静态库构建MicroRos的STM32移植实践
1. 环境准备与工具安装
在开始MicroROS的STM32移植之前,我们需要先搭建好开发环境。我选择的是Ubuntu 24.04系统,这个版本自带的CMake 3.28版本正好满足MicroROS的编译要求。如果你用的是其他Ubuntu版本,可能需要手动升级CMake,这点我后面会详细说明。
首先是ROS2 Jazzy的安装。我强烈推荐使用鱼香ROS的一键安装脚本,真的省心不少。安装完成后别忘了装上Colcon构建工具:
sudo apt-get install python3-colcon-common-extensions
接下来检查CMake版本,确保是3.28:
cmake --version
如果不是这个版本,可以通过添加官方仓库来升级。我之前用Ubuntu 20.04时就需要手动升级,过程有点折腾,所以直接使用24.04能省去不少麻烦。
STM32CubeMX的安装需要Java环境,先检查一下:
java -version
如果没有安装,运行:
sudo apt install default-jre
然后去ST官网下载Linux版本的STM32CubeMX,解压后直接运行安装脚本即可。记得给执行权限:
chmod +x SetupSTM32CubeMX
./SetupSTM32CubeMX
2. STM32工程配置详解
打开STM32CubeMX后,选择STM32F407ZGT6芯片。这里要特别注意,MicroROS需要较大的内存空间,建议选择RAM至少50KB的芯片。我之前试过STM32F103C8T6,只有20KB RAM,编译时直接报内存溢出错误。
关键配置步骤如下:
- 使能SYS中的Debug为Serial Wire
- 配置RCC为外部晶振
- 设置时钟树到最大频率(对于F407是168MHz)
- 启用USART3为异步模式并开启全局中断
- 配置DMA:RX为Circular模式,TX为Normal模式,优先级都是Very High
FreeRTOS配置中,需要为MicroROS任务分配3000字节的堆栈空间。这个值不能太小,否则运行时会出问题。我建议任务名可以自定义,比如"microROS_task"。
在Project Manager中,选择Toolchain为Makefile。这点很重要,因为我们后面要手动修改Makefile来集成静态库。
生成代码前,建议勾选"Generate peripheral initialization as a pair of .c/.h files per peripheral",这样代码结构更清晰。
3. MicroROS构建系统安装
现在来安装micro_ros_setup功能包。这个包是构建静态库的关键,即使不用Docker也要靠它:
source /opt/ros/$ROS_DISTRO/setup.bash
mkdir microros_ws
cd microros_ws
git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup
sudo apt update && rosdep update
rosdep install --from-paths src --ignore-src -y
sudo apt-get install python3-pip
colcon build
source install/local_setup.bash
这个过程可能会遇到网络问题,特别是rosdep update那步。如果失败,可以多试几次,或者换个网络环境。
4. 手动构建静态库的完整流程
4.1 获取工具库源码
在STM32工程目录下克隆工具库:
git clone https://github.com/micro-ROS/micro_ros_stm32cubemx_utils.git
这个库包含了我们需要的所有辅助文件和脚本。
4.2 定制构建脚本
这是最关键的一步。我们需要分析并修改library_generation.sh脚本,使其能在非Docker环境下工作。
先安装交叉编译工具链:
sudo apt update
sudo apt install -y gcc-arm-none-eabi
然后创建my_library_generation.sh,内容如下:
#!/bin/bash
set -e
export ROS_DISTRO=jazzy
export PROJECT=~/你的工程路径
export BASE_PATH=~/你的工程路径/micro_ros_stm32cubemx_utils/microros_static_library
source /opt/ros/$ROS_DISTRO/setup.bash
source install/local_setup.bash
ros2 run micro_ros_setup create_firmware_ws.sh generate_lib
# 后续内容保持原样...
注意要把PROJECT和BASE_PATH改成你的实际工程路径。这个脚本的核心是绕过了Docker,直接使用本地ROS2环境来构建。
4.3 修改工程Makefile
打开STM32工程的Makefile,在"build the application"之前添加:
#######################################
# micro-ROS addons
#######################################
LDFLAGS += micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a
C_INCLUDES += -Imicro_ros_stm32cubemx_utils/microros_static_library/libmicroros/microros_include
# Add micro-ROS utils
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/custom_memory_manager.c
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_allocators.c
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_time.c
# Set here the custom transport implementation
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_transports/dma_transport.c
print_cflags:
@echo $(CFLAGS)
特别注意@echo前面必须是Tab缩进,不能是空格,否则会报错。
4.4 执行构建
在microros_ws目录下运行:
bash ~/你的工程路径/micro_ros_stm32cubemx_utils/microros_static_library/library_generation/my_library_generation.sh
这个过程比较耗时,第一次运行需要下载很多依赖包。如果网络不好可能会失败,多试几次就好。
构建成功后,静态库会生成在libmicroros目录下。你可以检查一下文件大小,正常的libmicroros.a应该在几MB左右。
5. 代码集成与调试
5.1 添加MicroROS支持
将sample_main.c中的头文件复制到freertos.c的适当位置:
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <uxr/client/transport.h>
#include <rmw_microxrcedds_c/config.h>
#include <rmw_microros/rmw_microros.h>
#include <std_msgs/msg/int32.h>
接着复制传输函数声明:
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);
然后在MicroROS任务中替换为以下代码:
rmw_uros_set_custom_transport(
true,
(void *) &huart3,
cubemx_transport_open,
cubemx_transport_close,
cubemx_transport_write,
cubemx_transport_read);
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应用程序初始化
rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
allocator = rcl_get_default_allocator();
rclc_support_init(&support, 0, NULL, &allocator);
rclc_node_init_default(&node, "cubemx_node", "", &support);
rclc_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__);
}
msg.data++;
osDelay(10);
}
最后别忘了在文件开头添加:
#include <stdbool.h>
#include "usart.h"
5.2 编译与烧录
使用make命令编译工程:
make -j8
如果编译成功,会生成firmware.bin文件。我推荐使用ST-Link进行烧录,先安装ST-Link工具:
sudo apt update
sudo apt install -y git make cmake gcc g++ libusb-1.0-0.dev
git clone https://github.com/stlink-org/stlink
cd stlink
make release
sudo make install
sudo ldconfig
烧录命令:
st-flash write build/firmware.bin 0x8000000
5.3 配置MicroROS Agent
烧录完成后,通过USB连接STM32和Ubuntu。首先给串口设备权限:
sudo chmod 777 /dev/ttyACM0
然后安装并启动micro_ros_agent:
source install/local_setup.sh
ros2 run micro_ros_setup create_agent_ws.sh
ros2 run micro_ros_setup build_agent.sh
source install/local_setup.sh
ros2 run micro_ros_agent micro_ros_agent serial -b 115200 --dev /dev/ttyACM0
现在应该能看到Agent成功启动的信息。打开另一个终端,测试通信是否正常:
ros2 topic list
ros2 topic echo /cubemx_publisher
如果能看到不断增长的整数输出,恭喜你,移植成功了!
6. 常见问题与解决方案
在实际操作中,我遇到过不少坑,这里分享几个典型问题的解决方法。
编译错误:CMake版本不兼容 如果遇到CMake版本问题,可以手动安装新版CMake:
wget https://github.com/Kitware/CMake/releases/download/v3.28.0/cmake-3.28.0.tar.gz
tar -xzf cmake-3.28.0.tar.gz
cd cmake-3.28.0
./bootstrap
make -j4
sudo make install
静态库构建失败 有时候因为网络问题,依赖包下载不全。可以尝试多次运行构建脚本,或者手动下载缺失的包。
内存不足错误 如果编译时提示内存不足,可能是STM32芯片选型问题。MicroROS需要至少50KB RAM,建议使用F4系列或更高性能的芯片。
串口通信失败 检查接线是否正确,串口设备权限是否足够。可以用minicom测试串口是否正常工作:
sudo apt install minicom
minicom -D /dev/ttyACM0 -b 115200
Agent连接超时 确保波特率设置正确(115200),并且STM32程序已经正确烧录。有时候重启一下Agent就能解决。
通过这次实践,我深刻体会到非Docker环境虽然前期配置麻烦一些,但对理解底层机制很有帮助。希望这份经验能帮你少走弯路,顺利实现MicroROS的移植。
更多推荐
所有评论(0)