ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

【瑞萨 MicroROS 评测】micro‑ROS 外设实践及进阶挑战

【瑞萨 MicroROS 评测】micro‑ROS 外设实践及进阶挑战 【瑞萨 MicroROS 评测】micro‑ROS 外设实践外设实践①ROS2 控制 RA6M4 板载 LED前言上一篇完成micro‑ROS底层移植实现MCU与Agent握手通信。本篇基于已搭建好的节点框架实现ROS2订阅者订阅LED控制话题上位机下发消息MCU完成板载LED开关控制。1 硬件资源板载LEDGPIO输出引脚通信USB‑CDCmicro‑ROS与Agent通信2 功能设计订阅话题/led_control消息类型std_msgs/msg/BoolTrue点亮LEDFalse熄灭LED3 订阅者代码实现#includerclc/rclc.h#includestd_msgs/msg/bool.hrcl_subscription_tled_sub;std_msgs__msg__Bool led_msg;// 订阅回调函数voidled_callback(constvoid*msgin){conststd_msgs__msg__Bool*msg(conststd_msgs__msg__Bool*)msgin;if(msg-data){R_GPIO_PinWrite(LED_PIN,BSP_IO_LEVEL_LOW);}else{R_GPIO_PinWrite(LED_PIN,BSP_IO_LEVEL_HIGH);}}// 订阅者初始化voidmicroros_led_sub_init(rclc_node_t*node,rclc_executor_t*executor){RCCHECK(rclc_subscription_init_default(led_sub,node,ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs,msg,Bool),led_control));RCCHECK(rclc_executor_add_subscription(executor,led_sub,led_msg,led_callback,ON_NEW_DATA));}4 主逻辑调用节点初始化完成后调用microros_led_sub_init()主循环持续执行rclc_executor_spin_some()。while(1){rclc_executor_spin_some(executor,RCL_MS_TO_NS(10));}5 整机测试流程J‑Link下载固件板子上电Ubuntu启动micro‑ROS Agentros2 run micro_ros_agent micro_ros_agent serial--dev/dev/ttyACM0新开终端发布话题控制LEDros2 topic pub /led_control std_msgs/msg/Bool{data: true}ros2 topic pub /led_control std_msgs/msg/Bool{data: false}观察开发板LED跟随指令亮灭。执行 pub true板子 LED 点亮pub false 熄灭6 实操踩坑记录问题1 发布话题LED无响应现象上位机正常发布消息回调函数不触发调试思路executor、订阅初始化、话题名称根因订阅未加入executor话题名字大小写不匹配解决方案确认rclc_executor_add_subscription执行成功严格核对话题名称。问题2 运行一段时间偶发HardFault现象空闲一段时间后随机死机调试思路栈大小回调函数内部处理逻辑根因回调函数栈溢出回调中执行耗时阻塞操作解决方案调大任务栈回调内部只做IO赋值禁止延时、循环阻塞。问题3 Agent握手成功ROS2找不到话题现象ros2 topic list看不到订阅话题调试思路micro‑ROS资源配置colcon.meta根因最大订阅数量配置过小解决方案修改RMW_UXRCE_MAX_SUBSCRIPTIONS重新编译libmicroros.a。7 小结完成ROS2订阅者开发实现上位机远程控制MCU板载LED。【瑞萨 MicroROS 评测】micro‑ROS 外设实践②板载按键中断采集并发布 ROS2 Topic前言实现了ROS2订阅控制板载LED。使用外部中断捕获板载按键按键触发后向上位机发布Bool类型Topic实现MCU硬件事件上报ROS2。1 硬件资源板载按键GPIO外部下降沿中断通信USB‑CDC micro‑ROS注意中断服务函数内禁止调用micro‑ROS API仅置标志位在主循环处理发布。2 功能设计发布话题/key_event消息类型std_msgs/msg/Bool按键按下发布data:true按键松开发布data:false中断仅设置事件标志消息发布放在主循环executor上下文执行。3 代码实现#includerclc/rclc.h#includestd_msgs/msg/bool.hrcl_publisher_tkey_pub;std_msgs__msg__Bool key_msg;volatilebool key_press_flagfalse;//按键外部中断回调voidkey_exti_callback(void){key_press_flagtrue;}//发布者初始化voidmicroros_key_pub_init(rclc_node_t*node){RCCHECK(rclc_publisher_init_default(key_pub,node,ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs,msg,Bool),key_event));}//按键状态检测与消息发送放在主循环调用voidkey_process(void){if(key_press_flag){key_press_flagfalse;key_msg.datatrue;rcl_publish(key_pub,key_msg,NULL);}}4 主循环逻辑while(1){key_process();rclc_executor_spin_some(executor,RCL_MS_TO_NS(10));}5 整机测试流程J‑Link下载固件Ubuntu启动micro‑ROS Agentros2 run micro_ros_agent micro_ros_agent serial--dev/dev/ttyACM0新开终端监听话题ros2 topicecho/key_event按下板载按键终端收到按键事件消息。中断设置6 实操踩坑记录问题1 按键按下没有消息发布现象中断可以进入标志位置1但没有ROS消息输出调试思路中断标志清除、主循环调用逻辑、publisher初始化根因中断标志未清零publisher未正确初始化解决方案FSP中断回调中清除中断标志确认microros_key_pub_init成功执行。问题2 频繁按键直接HardFault死机现象快速反复按键固件崩溃调试思路中断服务函数内容、micro‑ROS API调用位置根因在中断内部直接调用rcl_publishmicro‑ROS非中断安全解决方案中断中只设置volatile标志发布操作放到主循环。问题3 消息丢包部分按键事件收不到现象部分按键按下上位机无输出调试思路USB‑CDC缓冲区micro‑ROS发布速率根因短时间大量消息挤压传输缓冲区溢出解决方案增加按键软件消抖限制消息发布频率。7 小结完成外部中断按键采集MCU硬件事件上报ROS2话题【瑞萨 MicroROS 评测】micro‑ROS 外设实践③MCU 系统状态监控节点前言前面完成LED订阅控制、按键事件上报。本篇搭建系统状态监控节点周期性上报MCU运行时长、USB‑CDC缓冲区溢出计数、Agent心跳连接状态实现对micro‑ROS链路健康监测。1 功能设计发布话题/mcu/status消息类型diagnostic_msgs/msg/DiagnosticStatus上报内容MCU运行时间msUSB‑CDC接收缓冲区溢出次数Agent心跳状态在线/离线发布周期1Hz1秒上报一次状态。2 全局变量定义#includerclc/rclc.h#includediagnostic_msgs/msg/diagnostic_status.hrcl_publisher_tstatus_pub;diagnostic_msgs__msg__DiagnosticStatus status_msg;uint32_tmcu_run_ms0;uint32_tusb_cdc_overflow_cnt0;bool agent_onlinefalse;rcl_time_point_value_tlast_agent_time;3 发布者初始化voidmicroros_status_pub_init(rclc_node_t*node){RCCHECK(rclc_publisher_init_default(status_pub,node,ROSIDL_GET_MSG_TYPE_SUPPORT(diagnostic_msgs,msg,DiagnosticStatus),/mcu/status));}4 状态更新与发布函数voidmcu_status_update(void){//获取系统毫秒计时mcu_run_msR_Delay_GetMilliseconds();//心跳判断超过1.5s没有通信判定Agent离线rcl_time_point_value_tnow;rcl_clock_get_now(rcl_get_default_clock(),now);agent_online((now-last_agent_time)RCL_MS_TO_NS(1500));status_msg.levelagent_online?0:1;status_msg.messageagent_online?Agent connected:Agent disconnected;status_msg.hardware_id.dataRA6M4;status_msg.hardware_id.size5;//填充键值对diagnostic_msgs__msg__KeyValue kv_run,kv_overflow;kv_run.key.datarun_time_ms;kv_run.value.dataitoa(mcu_run_ms,kv_run.value.data,10);kv_overflow.key.datausb_overflow;kv_overflow.value.dataitoa(usb_cdc_overflow_cnt,kv_overflow.value.data,10);status_msg.values.data[0]kv_run;status_msg.values.data[1]kv_overflow;status_msg.values.size2;rcl_publish(status_pub,status_msg,NULL);}5 主循环逻辑uint32_tstatus_timer0;while(1){key_process();//1Hz周期上报状态if(R_Delay_GetMilliseconds()-status_timer1000){status_timerR_Delay_GetMilliseconds();mcu_status_update();}rclc_executor_spin_some(executor,RCL_MS_TO_NS(10));//通信有数据更新心跳时间if(transport_rx_activity_flag){transport_rx_activity_flagfalse;rcl_clock_get_now(rcl_get_default_clock(),last_agent_time);}}在USB‑CDC接收中断中当发生缓冲区溢出时对usb_cdc_overflow_cnt收到有效数据包置位transport_rx_activity_flag。6 整机测试流程J‑Link下载固件启动micro‑ROS Agentros2 run micro_ros_agent micro_ros_agent serial--dev/dev/ttyACM0终端监听状态话题ros2 topicecho/mcu/status断开Agent可以观察状态切换为离线重启Agent自动恢复在线。输出结果state: 1msg: “mcu online”state: 1msg: “mcu online”7 实操踩坑记录问题1 DiagnosticStatus消息发布乱码现象收到消息字符串乱码调试思路ros2字符串内存管理根因字符串临时栈内存消息发送完成内存失效解决方案使用全局static字符数组存储字符串内容。问题2 Agent断开后状态不会切换离线现象关闭Agent状态一直显示connected调试思路心跳时间戳更新逻辑根因没有清除接收活动标记时间戳不刷新解决方案仅当Transport收到有效数据包才刷新last_agent_time。问题3 高负载下USB溢出计数持续上涨现象高速收发时usb_overflow持续累加调试思路USB‑CDC接收缓冲区大小根因USB中断处理不及时接收FIFO溢出解决方案调大USB‑CDC接收缓冲区降低micro‑ROS消息发布频率。8 小结完成MCU系统监控节点实现运行时间、USB溢出计数、Agent在线心跳检测。【瑞萨 MicroROS 评测】micro‑ROS 外设实践④ROS2 下发字符串控制 OLED 显示 本地 Agent 离线诊断前言上一篇完成MCU系统状态监控节点。本篇实现字符串订阅功能上位机下发字符串OLED屏幕实时显示增加离线诊断逻辑Agent断开连接时OLED本地打印故障信息脱离ROS2也可查看状态。1 硬件资源OLEDI2C SSD1306 0.96寸通信USB‑CDC micro‑ROS本地离线模式Agent离线OLED直接展示MCU内部状态2 功能设计订阅话题/oled/display消息类型std_msgs/msg/String上位机下发字符串OLED刷新显示文本内容Agent离线状态下OLED自动切换本地诊断界面运行时长、USB溢出计数、链路状态3 代码实现#includerclc/rclc.h#includestd_msgs/msg/string.hrcl_subscription_toled_sub;std_msgs__msg__String oled_msg;//ROS字符串订阅回调voidoled_callback(constvoid*msgin){conststd_msgs__msg__String*msg(conststd_msgs__msg__String*)msgin;oled_clear();oled_show_string(0,0,msg-data.data);}//订阅初始化voidmicroros_oled_sub_init(rclc_node_t*node,rclc_executor_t*executor){RCCHECK(rclc_subscription_init_default(oled_sub,node,ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs,msg,String),/oled/display));RCCHECK(rclc_executor_add_subscription(executor,oled_sub,oled_msg,oled_callback,ON_NEW_DATA));}//离线诊断页面刷新voidoled_offline_diagnostic(uint32_trun_ms,uint32_toverflow_cnt){oled_clear();oled_show_string(0,0,Agent OFFLINE);charbuf[32];sprintf(buf,Run:%d ms,run_ms);oled_show_string(0,16,buf);sprintf(buf,USB_O:%d,overflow_cnt);oled_show_string(0,32,buf);}4 主循环逻辑while(1){key_process();if(R_Delay_GetMilliseconds()-status_timer1000){status_timerR_Delay_GetMilliseconds();mcu_status_update();}rclc_executor_spin_some(executor,RCL_MS_TO_NS(10));if(transport_rx_activity_flag){transport_rx_activity_flagfalse;rcl_clock_get_now(rcl_get_default_clock(),last_agent_time);}//心跳判断rcl_time_point_value_tnow;rcl_clock_get_now(rcl_get_default_clock(),now);agent_online((now-last_agent_time)RCL_MS_TO_NS(1500));//离线自动切诊断界面if(!agent_online){oled_offline_diagnostic(mcu_run_ms,usb_cdc_overflow_cnt);}}5 整机测试流程J‑Link下载固件OLED接I2C引脚Ubuntu启动Agentros2 run micro_ros_agent micro_ros_agent serial--dev/dev/ttyACM0下发字符串命令ros2 topic pub /oled/display std_msgs/msg/String{data:\RA6M4 Micro‑ROS Test\}OLED屏幕显示下发文本关闭Agent屏幕自动切换离线诊断页面。6 实操踩坑记录问题1 长字符串下发后固件死机现象发送较长字符串HardFault调试思路std_msgs/String内存分配根因String消息未分配足够缓冲区内存越界解决方案修改colcon.meta调大字符串最大长度给msg.data分配全局buffer。问题2 Agent断开OLED画面闪烁现象离线诊断页面每秒反复刷新闪烁调试思路页面刷新频率控制根因主循环无条件每秒重复刷屏解决方案增加状态标记状态发生改变才执行oled刷新。问题3 部分中文乱码现象下发中文OLED输出乱码调试思路OLED字库根因SSD1306无内置中文字库解决方案仅使用ASCII字符如需中文需要点阵字库。7 小结完成ROS字符串下发控制OLED显示实现Agent离线本地诊断显示。【瑞萨 MicroROS 评测】进阶挑战 FreeRTOSmicro‑ROS前言前面全部基于裸机环境完成micro‑ROS开发。迁移至FreeRTOS操作系统把micro‑ROS executor放到独立任务运行隔离IO、按键、显示业务解决裸机主循环阻塞带来的通信卡顿问题。1 环境说明MCURA6M4RTOSFreeRTOSFSP自带通信USB‑CDC transportmicro‑ROS运行于独立RTOS任务优先级中等2 系统架构设计microros_task专门运行rclc_executor_spin_some处理订阅、发布、XRCE‑DDS协议栈空间调大ui_taskOLED显示、离线诊断刷新key_task按键状态处理禁止在中断、其他任务直接调用micro‑ROS API所有rclc接口统一在microros_task内部执行。3 RTOS任务创建代码#includeFreeRTOS.h#includetask.h#defineMICROROS_TASK_STACK_SIZE(4096)#defineUI_TASK_STACK_SIZE(1024)staticTaskHandle_t microros_task_handle;staticTaskHandle_t ui_task_handle;voidmicroros_task(void*pvParameters){(void)pvParameters;//micro‑ROS初始化放在本任务内app_microros_init();microros_led_sub_init(node,executor);microros_key_pub_init(node);microros_status_pub_init(node);microros_oled_sub_init(node,executor);for(;;){rclc_executor_spin_some(executor,RCL_MS_TO_NS(10));vTaskDelay(pdMS_TO_TICKS(10));}}voidui_task(void*pvParameters){(void)pvParameters;for(;;){//OLED刷新、离线诊断逻辑if(!agent_online){oled_offline_diagnostic(mcu_run_ms,usb_cdc_overflow_cnt);}vTaskDelay(pdMS_TO_TICKS(500));}}//在main中创建任务voidrtos_app_create_tasks(void){xTaskCreate(microros_task,microros,MICROROS_TASK_STACK_SIZE,NULL,2,microros_task_handle);xTaskCreate(ui_task,ui,UI_TASK_STACK_SIZE,NULL,1,ui_task_handle);}4 资源与配置关键点FreeRTOS栈micro‑ROS任务栈至少4096字节栈过小直接HardFault优先级micro‑ROS任务优先级高于UI任务保证通信实时性HeapFreeRTOS heap5堆空间增大供micro‑ROS分配Transport USB‑CDC中断保持不变中断仅置标志不调用rcl接口多任务共享变量agent_online、mcu_run_ms等访问加临界区保护。//共享变量读取示例uint32_tget_mcu_run_ms(void){uint32_tval;taskENTER_CRITICAL();valmcu_run_ms;taskEXIT_CRITICAL();returnval;}5 整机测试流程FSP开启FreeRTOS生成工程J‑Link下载固件Ubuntu启动Agentros2 run micro_ros_agent micro_ros_agent serial--dev/dev/ttyACM0执行各项ROS话题测试LED控制、按键上报、OLED字符串下发、状态监控长时间压测观察是否出现死锁、死机、断连。6 实操踩坑记录问题1 一跑micro‑ROS任务直接HardFault现象进入任务立刻硬件错误调试思路任务栈大小FPU上下文保存根因栈空间不足FreeRTOS未开启FPU浮点上下文保存解决方案调大任务栈FSP中FreeRTOS勾选Use FPU。问题2 随机发生死锁通信完全停止现象Agent握手成功一段时间后不再响应任何话题调试思路多任务共享资源中断与RTOS冲突根因多任务无保护读写micro‑ROS句柄、全局状态变量解决方案micro‑ROS全部API只在microros_task执行共享变量用临界区保护。问题3 高负载下USB‑CDC接收丢包变多现象RTOS调度切换频繁USB中断延迟调试思路USB中断优先级根因USB中断优先级过低被其他中断抢占解决方案提升USB外设中断优先级保证USB中断及时响应。7 小结完成FreeRTOS下micro‑ROS部署使用独立任务运行executor业务解耦解决裸机循环阻塞带来通信卡顿。完整覆盖RA6M4平台micro‑ROS从环境搭建、底层移植、外设实践、USB‑CDC通信到RTOS移植全流程。一些相关演示视频按键控制话题输出mcu/status 在线周期性输出
返回列表