来源 | 瑞萨嵌入式小百科
在上一篇文章《》中,我们已经在RA6M4上用e² studio+FSP跑通了Micro-ROS UART通信。
在本文中,我们将通过Zephyr运行Micro-ROS UART通信,最终验证目标:RA6M4通过板载CH340对应的SCI9 UART与Ubuntu上的Micro-ROS Agent通信,并在ROS 2中发布一个持续递增的/int_publisher数据。



前言
本次移植工作的核心可以概括为三件事。
1 | 完成RA-ECO-RA6M4的Zephyr板级适配 由于Zephyr已经支持EK-RA6M4,我们只需补充开发板层面的board文件,包括时钟、Flash/RAM、J-Link烧录方式,以及板载CH340对应的SCI9 UART引脚配置。 |
2 | 编写一个最小Micro-ROS应用 在Zephyr应用中创建Micro-ROS节点、publisher和timer,让RA6M4周期性发布一个std_msgs/msg/Int32数据,验证MCU到ROS 2的通信链路。 |
3 | 接入并适配micro_ros_zephyr_module 这部分负责生成MCU端需要的libmicroros.a静态库,并把Micro-ROS的串口transport对接到Zephyr UART驱动,最终通过Micro-ROS Agent接入ROS 2。 |

点击可查看大图
Oracle VirtualBox
Ubuntu 22.04
ROS 2 Humble
Micro-ROS Agent
Zephyr v4.2.0
Zephyr SDK 0.17.3 Linux版
J-Link
注意事项
本次开发包括Zephyr环境均在Linux环境下完成。


板级文件
从EK-RA6M4到RA-ECO-RA6M4
因为瑞萨RA全系列都有Zephyr官方适配包,所以我们只需要根据官方给的EK-RA6M4板级支持文件,为RA-ECO-RA6M4这块开发板补充一份out-of-tree board文件即可。

主要文件结构如下:

点击可查看大图
这边还没有加入LED、按键、I2C、USB或Ethernet,只加入UART模块需要功能。目的只是让Zephyr能够正常启动并通过板载CH340对应的UART输出Hello World。
根据此前在e² studio/FSP中验证过的硬件连接,RA-ECO-RA6M4的板载CH340使用SCI9,对应引脚为:

点击可查看大图
因此,需要在ra_eco_ra6m4-pinctrl.dtsi中配置SCI9的pinctrl:

点击可查看大图
随后在ra_eco_ra6m4.dts中,把Zephyr默认console指向uart9:

点击可查看大图
同时启用SCI9:

点击可查看大图
RA-ECO-RA6M4使用的是12 MHz外部晶振。参考此前FSP工程中的时钟配置,需要在Zephyr中设置XTAL和PLL:

点击可查看大图
第一次编译自定义board时,Zephyr已经能识别RA-ECO-RA6M4,但出现了系统时钟断言错误。原因是当前配置后的系统时钟为180 MHz,而部分默认配置仍沿用了EK-RA6M4的200 MHz。
解决方法是在ra_eco_ra6m4_defconfig中明确设置:

点击可查看大图


应用文件
编写Zephyr Micro-ROS程序

核心文件包括:

点击可查看大图
CMakeLists.txt是Zephyr应用的构建入口,用来声明当前目录是一个Zephyr application,并把src/main.c加入编译。同时,它需要让Zephyr构建系统能够找到外部的micro_ros_zephyr_module。
prj.conf是应用配置文件。这里打开串口、UART中断、console、Micro-ROS,以及Micro-ROS的serial transport:

点击可查看大图
这部分配置的核心思路是:Zephyr侧启用UART能力,Micro-ROS侧选择serial transport,并根据应用规模限制节点、publisher、subscriber等资源数量,避免无意义占用MCU内存。
src/main.c负责以下工作:

点击可查看大图
本次应用创建的节点和话题为:

点击可查看大图
其中比较关键的一步是transport绑定。Micro-ROS本身并不直接关心底层是UART、USB还是UDP,它只需要一组open、close、write、read接口。因此在应用启动时需要调用:

点击可查看大图
把Zephyr module提供的串口transport函数传给Micro-ROS。这样,Micro-ROS发出的XRCE-DDS数据就会通过Zephyr UART驱动,经由SCI9和CH340发送到Ubuntu中运行的Micro-ROS Agent。


micro_ros_zephyr_module
接入micro-ROS静态库和transport
这块不是我们从零编写的,而是Micro-ROS社区提供的Zephyr适配模块。它的作用是把Micro-ROS的源码包、构建流程、静态库和transport接入Zephyr工程。

关键文件包括:

点击可查看大图

其中:
module.yml用来把该目录注册为Zephyr module。
Kconfig提供CONFIG_MICROROS、CONFIG_MICROROS_TRANSPORT_SERIAL等配置项。
CMakeLists.txt负责把生成好的libmicroros.a链接进Zephyr应用。
libmicroros.mk负责执行Micro-ROS静态库构建,拉取并编译rcl、rclc、rmw_microxrcedds、microxrcedds_client等组件。
colcon.meta用来控制Micro-ROS静态库的构建参数,例如节点数量、publisher数量、XRCE-DDS MTU、history深度等。
zephyr_toolchain.cmake.in用来把Zephyr的交叉编译参数传递给Micro-ROS的colcon构建过程。
microros_transports\serial\则是Zephyr UART transport的实现。


构建与运行验证

实际构建时,命令形式如下:

点击可查看大图
执行west build后,构建日志中如果能看到Micro-ROS module被加载,并开始执行libmicroros.mk、colcon build,就说明已经进入Micro-ROS静态库构建阶段。第一次构建耗时会比较长,需要准备Micro-ROS相关源码和依赖包。
构建完成后,重点检查三个文件:

点击可查看大图
如果libmicroros.a存在,说明Micro-ROS MCU端静态库已经生成。如果zephyr.hex存在,说明它已经被成功链接进最终固件。
在Ubuntu中完成构建后,将固件通过J-Link烧录到RA-ECO-RA6M4。运行前,先在Ubuntu中启动Micro-ROS Agent:

点击可查看大图
随后按下开发板复位键。如果通信正常,Agent会显示Micro-ROS client建立session,并持续收到来自MCU的XRCE-DDS数据。
此时再查看ROS 2话题,就能看到RA6M4发布的/int_publisher数据。
这个结果说明,RA6M4已经不只是通过串口打印普通字符串,而是作为一个标准Micro-ROS节点接入了ROS 2通信系统。

------------ END ------------





