RT-Thread支持的bsp没有RA6M4,但是已经支持了ra6m4-cpk、ra6m4-iot,可以通过简单地修改得到支持RA6M4的bsp。假设我们已经经过修改得到这个bsp,姑且按照开发板的名称叫RA-Eco-RA6M4,位于:rt-thread\bsp\renesas\RA-Eco-RA6M4。现在开始搭建RT-Thread下的Micro-ROS。
rt-thread提供了很多在线的组件,通常可以在menuconfig->RT-Thread online packages中进行选择,然后通过pkg --update,从官方网站上下载组件到packages目录下。按照这个思路,从RT-Thread online packages → system packages中也找到micro-ROS package for RTThread组件,但是pkg --update并没有下载更新这个组件。
micro-ROS package for RTThread提供了专门的安装方式,可以参考https://github.com/micro-ROS/micro_ros_rtthread_component中的README.MD,据此描述一下我的搭建过程。
一、RT-Thread online packages搭建过程
1、建立一个基于cmake的dist
scons --target=cmake --dist --project-name=RA6M4\_test1cd dist/RA6M4_test/packages
2、拉取库
cd dist/RA6M4_test/packages
git clone https://github.com/micro-ROS/micro_ros_rtthread_component.git
3、将组件加到RT-Thread env环境
复制packages\micro_ros_rtthread_component\package\下的micro_ros_rtthread_package文件夹到 env环境下的\packages目录下

更新env环境下packages\Kconfig文件中:

source "$PKGS_DIR/packages/Kconfig"
source "$PKGS_DIR/micro_ros_rtthread_package/Kconfig"
再使用menuconfig配置的主菜单中就会发现多出了micro_ros_rtthread_component,这次不是在RT-Thread online packages → system packages中。

4、micro_ros_rtthread_component配置

选择发行版:Humble
选择通讯方式:serial
不用选择例程,因为要自己写。
而具体使用哪个串口,还要在RT-Thread online packages → system packages -> micro_ros_rtthread_package 中设置:


5、构建
没有写代码,但现在就可以构建:
scons --build_microros
该命令会首先调用micro_ros_rtthread_component\builder\microros_utils下的脚本,判断是否以存在libmicroros.a静态库,如果没有会拉取相关依赖库,编译生成一个,然后再编译应用,如果有libmicroros.a静态库,则直接编译应用。
因为编译libmicroros.a静态库过程要从git上拉取很多库,而且如果中间失败,就会删除已下载的临时文件,然后再重新下载,可以说一般国内用户是不可能编译成功的。
我通过注释分步注释micro_ros_rtthread_component\builder\microros_utils\library_builder.py
# Delete previous build folders
#rmtree(self.temp_folder)
#os.makedirs(self.temp_folder)
#self.download_dev_environment()
#self.apply_patchs(self.dev_src_folder)
#self.build_dev_environment()
#self.download_mcu_environment()
#self.download_extra_packages()
#self.apply_patchs(self.mcu_src_folder)
self.build_mcu_environment(toolchain, user_meta)
self.package_mcu_library()
# Delete generated build folders
#rmtree(self.temp_folder)
执行过程中已成功步骤,花了很长时间总算编译出libmicroros.a,大概20多兆,而本次评测资料中提供的micro_ros_renesas2estudio_component中libmicroros.a只有5M。
实际上用本次评测资料中提供的micro_ros_renesas2estudio_component中libmicroros.a及相关头文件复制到packages\micro_ros_rtthread_component\builder目录中,与自己编译效果一样。
二、RT-Thread编译Micro-ROS代码
在工程src目录下新建microros_pub.c
#include <rtthread.h>
#if defined PKG_MICRO_ROS_USE_SERIAL
#include <micro_ros_rtt.h>
#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <std_msgs/msg/int32.h>
#define DBG_TAG "pub_example"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
static rcl_publisher_t publisher;
static std_msgs__msg__Int32 msg;
static rclc_executor_t executor;
static rclc_support_t support;
static rcl_allocator_t allocator;
static rcl_node_t node;
static rcl_timer_t timer;
static void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
// RCLC_UNUSED(last_call_time);
if (timer != NULL)
{
rcl_publish(&publisher, &msg, NULL);
msg.data++;
}
else {
rt_kprintf("[micro_ros] timer null\n");
}
}
static void microros_pub_int32_thread_entry(void *parameter)
{
while(1)
{
rt_thread_mdelay(100);
rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
}
}
static void microros_pub_int32(int argc, char* argv[])
{
// Serial setup
set_microros_transports();
allocator = rcl_get_default_allocator();
rt_kprintf("rcl_get_default_allocator\n");
//create init_options
if (rclc_support_init(&support, 0, NULL, &allocator) != RCL_RET_OK)
{
rt_kprintf("[micro_ros] failed to initialize\n");
return;
};
rt_kprintf("rclc_support_init\n");
// create node
if (rclc_node_init_default(&node, "micro_ros_rtt_node", "", &support) != RCL_RET_OK)
{
rt_kprintf("[micro_ros] failed to create node\n");
return;
}
rt_kprintf("[micro_ros] node created\n");
// create publisher
rclc_publisher_init_default(
&publisher,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
"micro_ros_rtt_node_publisher");
rt_kprintf("[micro_ros] publisher created\n");
// create timer
const unsigned int timer_timeout = 1000;
rclc_timer_init_default(
&timer,
&support,
RCL_MS_TO_NS(timer_timeout),
timer_callback);
rt_kprintf("[micro_ros] timer created\n");
// create executor
rclc_executor_init(&executor, &support.context, 1, &allocator);
rclc_executor_add_timer(&executor, &timer);
rt_kprintf("[micro_ros] executor created\n");
msg.data = 0;
rt_thread_t thread = rt_thread_create("mr_pubint32", microros_pub_int32_thread_entry, RT_NULL, 2048, 25, 10);
if(thread != RT_NULL)
{
rt_thread_startup(thread);
rt_kprintf("[micro_ros] New thread mr_pubint32\n");
}
else
{
rt_kprintf("[micro_ros] Failed to create thread mr_pubint32\n");
}
}
MSH_CMD_EXPORT(microros_pub_int32, microros publish int32 example)
#endif // PKG_MICRO_ROS_USE_SERIAL
三、运行
1、硬件连接

2、启动micro_ros_agent
cd ~/microros_ws
source /opt/ros/humble/setup.bash
source install/local_setup.bash
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0

3、rt-thread msh运行micro-ros应用


4、查看发布话题内容
ros2 topic list

ros2 topic echo /micor_ros_rtt_node_publisher
