【瑞萨 MicroROS 评测】VMware虚拟机Ubuntu22.04搭建 + ROS2 Humble + micro‑ROS‑Agent编译编译配合libmicroros.a 静态库
一.VMware虚拟机Ubuntu22.04搭建 + ROS2 Humble + micro‑ROS‑Agent编译编译
1
针对瑞萨RA6M4裸机/FreeRTOS平台完成micro‑ROS全流程移植。本篇完成上位机Ubuntu环境部署,以及VMware虚拟机部署方案,使用国内镜像解决外网下载超时,完成ROS2 Humble、micro‑ROS‑Agent、交叉编译依赖安装,为后续micro‑ROS静态库编译做准备。
2.1 VMware虚拟机精准硬件配置
- 新建虚拟机→典型模式,挂载
ubuntu‑22.04‑desktop‑amd64.iso镜像 - 硬件参数:
- CPU:8核心
- 内存:≥4GB
- 网络适配器:桥接模式
- USB控制器开启USB3.1,保证J‑Link、USB‑CDC设备可正常映射至虚拟机
软件
虚拟机配置
2.2 Ubuntu系统初始化(解决国内下载慢、超时)
2.2.1 替换清华软件源
# 备份原有源sudocp/etc/apt/sources.list /etc/apt/sources.list.bak# 写入清华源sudotee/etc/apt/sources.list<<-'EOF' deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse EOFsudoaptupdate&&sudoaptupgrade-y2.2.2 安装全套依赖(编译Micro‑ROS、交叉编译必备)
sudoaptinstallgitpython3-pip build-essential cmake gcc-arm-none-eabi g++ crossbuild-essential-armhf python3-venv pip3installempy lark packaging setuptools--upgrade-ihttps://pypi.tuna.tsinghua.edu.cn/simple2.2.3 清华源安装 ROS2 Humble(规避外网拉取失败)
sudoaptinstallsoftware-properties-commonsudoadd-apt-repository universesudoaptupdate&&sudoaptinstallcurlgnupg lsb-release# 导入ROS密钥curl-shttps://mirrors.tuna.tsinghua.edu.cn/rosdistro/ros.key|sudogpg--dearmor-o/usr/share/keyrings/ros-archive-keyring.gpg# 添加ROS软件源echo"deb [arch=$(dpkg --print-architecture)signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu jammy main"|sudotee/etc/apt/sources.list.d/ros2.list>/dev/nullsudoaptupdate# 桌面完整版+microROS agent桥接工具sudoaptinstallros-humble-desktop ros-humble-micro-ros-agent# 持久化ROS环境变量echo"source /opt/ros/humble/setup.bash">>~/.bashrcsource~/.bashrc2.2.4 安装VMware Tools,实现Windows与虚拟机文件互通
sudoaptinstallopen-vm-tools open-vm-tools-desktop-yreboot重启后在VMware「虚拟机‑设置‑选项‑共享文件夹」配置Windows共享目录,用来传输编译完成的Micro‑ROS SDK压缩包。
3 基础环境验证
#验证ROS2ros2--version#验证micro‑ROS Agentros2 run micro_ros_agent micro_ros_agent--help#验证ARM交叉编译器arm-none-eabi-gcc-v需删除盲文辅助功能,否则占用串口
sudoaptpurge --auto-remove brltty-yls/dev/ttyUSB*#成功显示:/dev/ttyUSB04 实操踩坑记录(原有内容完整保留,补充虚拟机新增坑点)
问题1 桥接模式虚拟机无法上网
现象:Ubuntu无网络
调试思路:虚拟机网络模式,宿主机网卡
根因:桥接网卡选错物理网卡
解决方案:VMware桥接模式指定本机有线/无线网卡。
问题2 Windows下J‑Link/USB‑CDC无法映射进虚拟机
现象:虚拟机看不到USB设备
调试思路:VMware USB控制器版本
根因:USB控制器版本过低;Windows占用设备
解决方案:设置USB3.1;虚拟机菜单栏手动连接USB设备。
问题3 pip安装包报错超时
现象:pip外网拉取失败
根因:未指定国内pip镜像源
解决方案:命令增加-i https://pypi.tuna.tsinghua.edu.cn/simple。
问题4 Agent启动提示串口权限不足
现象:permission denied /dev/ttyACM0
解决方案:
sudochmod777/dev/ttyACM0成功建立话题如下
二.静态库编译方案
方案A:generate_lib 传统编译(原有完整保留,芯片绑定库)
1.1 拉取micro_ros_setup工具
mkdir-p~/ra6m4_uros&&cd~/ra6m4_urosgitclone https://github.com/micro-ROS/micro_ros_setup.gitcdmicro_ros_setup pip3install-rrequirements.txt-ihttps://pypi.tuna.tsinghua.edu.cn/simple1.2 创建固件编译工作区
cd~/ra6m4_uros ./micro_ros_setup/create_firmware_ws.sh humblecdfirmware_ws1.3 修改colcon.meta配置,裁剪micro‑ROS资源
修改firmware_ws/src/micro_ros_firmware/config-colcon.meta,调大内存,关闭不需要组件,适配MCU资源。
{"rmw_microxrcedds":{"cmake-args":["-DRMW_UXRCE_MAX_SESSIONS=1","-DRMW_UXRCE_MAX_NODES=1","-DRMW_UXRCE_MAX_PUBLISHERS=4","-DRMW_UXRCE_MAX_SUBSCRIPTIONS=4","-DRMW_UXRCE_MAX_HISTORY=4"]}}1.4 编译生成RA6M4专用libmicroros.a
cd~/ra6m4_uros/firmware_ws colcon build产物路径:firmware_ws/build/micro_ros_firmware/libmicroros.a,头文件位于install/include。
缺点:该库绑定预设transport,更换MCU、更换传输硬件(SCI串口/USB‑CDC)需要重新编译。
方案B:transport=none,编译无硬件绑定通用micro‑ROS静态库
2.1 获取micro_ros_setup编译脚本
mkdir~/uros_lib_build&&cd~/uros_lib_buildgitclone https://github.com/micro-ROS/micro_ros_setup.gitcdmicro_ros_setup pip3install-rrequirements.txt-ihttps://pypi.tuna.tsinghua.edu.cn/simple2.2 创建静态库编译工作区
cd~/uros_lib_build ./micro_ros_setup/create_lib_ws.sh humblecdlib_ws/src/micro_ros_static_library_builder2.3 修改编译配置,生成通用Cortex‑M库
编辑library_generation.sh
#通用Cortex‑M架构,兼容STM32F4、瑞萨RA6M4/RA6M5TARGET_ARCH=cortex-m4TRANSPORT=none#剥离串口、USB、CAN硬件传输层,只编译micro‑ROS内核BUILD_TYPE=ReleaseENABLE_LOGGING=OFF#关闭日志,固件瘦身,调试阶段改为ONFPU=hard#硬件浮点,RA6M4带FPU,工程编译选项必须和该配置严格一致编辑同目录micro_ros_library.config,裁剪不需要组件,降低资源占用
RCL_SERVICE_SUPPORT=OFF RCL_PARAMETERS=OFF UROS_LOG_LEVEL=UROS_LOG_NONE RCL_DIAGNOSTICS=OFF TIME_SYNC_ENABLE=OFF2.4 编译静态库
cd~/uros_lib_build/lib_ws colcon build编译产物输出路径:lib_ws/install/
2.5 导出可移植SDK,打包传到Windows单片机工程
mkdir~/microROS_Generic_SDKcp-rinstall/include ~/microROS_Generic_SDK/cpinstall/lib/*.a ~/microROS_Generic_SDK/lib/tar-zcvfmicroROS_Humble_Universal.tar.gz microROS_Generic_SDKSDK分层说明
- 核心层(不可删除)
librcl.a、librclc.a、librmw_microxrcedds.a:节点、话题、发布订阅核心。 - 可选瘦身层(不用可以删除)
librcl_service.a、librcl_parameters.a、librcutils_logging.a,删除后ROM体积减少30%‑50%。 - 移植补充层:单片机端自行实现时间、内存、Transport三套硬件适配接口。
备选:Docker容器编译,适合宿主机环境混乱;自定义消息可在lib_ws/src添加消息包,colcon build后一并打包进SDK。
3 RA6M4工程导入micro‑ROS SDK(两种库通用导入流程)
- 将对应SDK的
include加入工程头文件搜索路径; - lib目录所有
.a静态库加入链接器; - 工程开启Hard FPU浮点,保证ABI和编译库完全匹配;
- 调大堆Heap,满足micro‑ROS内存分配需求。
注意:方案A生成库自带transport;使用方案B通用库,必须手动注册自定义transport回调。
4 RA6M4三层底层适配接口实现
4.1 Time系统时间接口
⚠️禁止使用RTC日历时钟,RTC可修改、时间跳变会造成XRCE‑DDS握手失败。RA6M4使用SysTick/DWT定时器输出单调递增纳秒时间戳。
#include<stdint.h>//返回纳秒,单调递增uint64_turos_get_time_ns(void){uint64_tms=R_Delay_GetMilliseconds();returnms*1000000ULL;}4.2 Allocator内存适配接口
裸机直接调用系统堆;FreeRTOS推荐内存池,避免长时间运行堆碎片化。
#include<stdlib.h>void*uros_malloc(size_tsize){#ifdefUSE_FREERTOSreturnpvPortMalloc(size);#elsereturnmalloc(size);#endif}voiduros_free(void*ptr){#ifdefUSE_FREERTOSvPortFree(ptr);#elsefree(ptr);#endif}将分配回调注册到micro‑ROS自定义allocator。
4.3 Transport传输层适配(RA6M4 USB‑CDC)
基于FSP USB‑PCDC驱动实现,使用环形缓冲区做非阻塞读写,禁止阻塞式API。
- transport_open:等待USB枚举完成
- transport_close:关闭USB外设
- transport_write:USB‑CDC发送数据包
- transport_read:从接收环形缓冲区拷贝数据,无数据返回0
仅方案B通用库需要手动注册自定义transport;方案A如果编译时选定USB‑CDC则不需要。
rmw_uros_set_custom_transport(true,NULL,transport_open,transport_close,transport_write,transport_read);5 最小micro‑ROS节点框架代码(原有保留)
rclc_node_tnode;rclc_executor_texecutor;voidapp_microros_init(void){rcl_init_options_tinit_options=rcl_get_zero_initialized_init_options();rcl_init_options_init(&init_options,rcl_get_default_allocator());rclc_support_tsupport;rclc_support_init(&support,0,NULL,&init_options);rclc_node_init_default(&node,"ra6m4_node","",&support);rclc_executor_init(&executor,&support.context,2,&support.allocator);}主循环调用
while(1){rclc_executor_spin_some(&executor,RCL_MS_TO_NS(10));}6 握手测试
- J‑Link下载固件;
- Ubuntu启动micro‑ROS Agent
ros2 run micro_ros_agent micro_ros_agent serial--dev/dev/ttyUSB0- 终端输出
Session established代表MCU与上位机握手成功。
7 实操踩坑记录(原有全部保留,补充新增方案坑点)
问题1 大量undefined reference
现象:链接阶段报大量micro‑ROS接口未定义
调试思路:静态库链接顺序,FPU ABI
根因:工程FPU配置与编译库不一致;静态库未全部链接
解决方案:工程开启hard浮点,完整导入全部.a库文件。
问题2 Agent运行正常,无法建立Session会话
现象:Agent仅running,无会话建立
调试思路:时间戳返回值、transport_read/write回调
根因:时间不是单调递增;USB‑CDC未完成枚举就打开transport
解决方案:使用SysTick/DWT时间,transport_open等待USB枚举完成。
问题3 固件HardFault死机
现象:一运行micro‑ROS直接硬件错误
调试思路:Heap大小、内存分配实现
根因:堆内存不足,内存越界访问
解决方案:调大HEAP_SIZE,检查malloc/free回调实现。
问题4 阻塞式transport_read导致整个系统卡死
现象:主循环停滞,外设全部失效
根因:transport_read使用阻塞等待接收
解决方案:实现环形缓冲区,非阻塞读取,无数据直接返回0。
问题5 方案B通用库编译后,忘记注册custom transport
现象:编译链接正常,上电无法握手
根因:TRANSPORT=none,没有默认传输实现
解决方案:必须调用rmw_uros_set_custom_transport注册传输回调。
8 两种编译方案对比总结
| 编译方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| generate_lib | 单芯片固定硬件项目 | 配置简单,开箱即用transport | 换芯片/换传输硬件需要重编译 |
| transport=none通用库 | 多芯片、竞赛大创项目 | 一份SDK多MCU复用,高度裁剪 | 需要完整实现全套底层适配 |