
嵌入式物联网机器人自动驾驶智能硬件【免费下载链接】PX4-AutopilotPX4 Autopilot Software项目地址https://gitcode.com/gh_mirrors/px/PX4-Autopilot点击查看免费下载MavlinkTunnel 是 PX4-Autopilot 中的一条 uORB 消息用于在 MAVLink 链路与板载外设如 ESC、I/O 协处理器之间承载MAV_TUNNEL数据包实现串口数据透传UART passthrough。本文基于 docs/en/msg_docs/MavlinkTunnel.md 与对应源码 msg/MavlinkTunnel.msg完整讲解其字段定义、payload 类型注册规则、主题别名机制并结合 mavlink_receiver.cpp 与 voxl_esc.cpp 等实现还原一条隧道数据从地面站发出到外设 UART 落地的完整调用链。读完本文你可以准确理解 MavlinkTunnel 的消息布局、如何自定义 payload 类型以及如何把隧道数据路由到指定的外设串口。消息概述用于 MAVLink 数据隧道的 uORB 载体MavlinkTunnel 对应 MAVLink 协议中的MAV_TUNNEL消息 ID 110报文。它的核心定位是把一段透明的字节载荷从 MAVLink 链路搬运到飞行控制器内部再通过 uORB 分发给订阅该消息的驱动最终写入某个外设的串口。典型应用包括ESC UART 透传地面站直接与电调ESC的串口固件通信用于调试、参数配置或固件升级I/O 协处理器 UART 透传与板载 I/O 芯片如 VOXL2 IO的串口交互通用隧道任意的自定义协议数据包通过mavlink_tunnel主题广播由用户程序订阅消费。在 PX4 的 uORB 体系中MavlinkTunnel 通过TOPICS声明定义了三个主题别名详见 msg/MavlinkTunnel.msg# TOPICS mavlink_tunnel esc_serial_passthru io_serial_passthru这三个主题共用同一套消息类型mavlink_tunnel_s但按载荷类型payload_type分流到不同的订阅者是理解整个隧道机制的关键。字段定义与字节布局消息定义源文件位于 msg/MavlinkTunnel.msg生成的 C 结构体为mavlink_tunnel_s对应头文件 uORB/topics/mavlink_tunnel.h。各字段含义如下字段类型说明timestampuint64系统启动以来的时间微秒由发布端MAVLink 接收模块以hrt_absolute_time()填充payload_typeuint16标识 payload 内容的编码0 表示未知默认。小于 32768 视为已注册类型需加入MAV_TUNNEL_PAYLOAD_TYPE枚举大于 32767 视为本地实验类型不应提交到广泛分发的代码库target_systemuint8目标系统 ID0 表示广播但不推荐target_componentuint8目标组件 ID0 表示广播但不推荐payload_lengthuint8payload 中实际携带数据的字节数payloaduint8[128]数据本体固定 128 字节缓冲区需要注意的关键细节payload_length是uint8_t最大 255而payload缓冲区固定为 128 字节。接收端会对长度做校验若payload_length sizeof(payload)整条消息会被直接丢弃见下文接收处理一节而不是截断转发——因为截断后的帧会破坏外设的串口协议。结构体内各字段顺序与 .msg 源文件一一对应发布与订阅双方通过 uORB 代码生成器保持布局一致。MAV_TUNNEL_PAYLOAD_TYPE 常量payload 类型注册规则MavlinkTunnel 在消息定义中内嵌了MAV_TUNNEL_PAYLOAD_TYPE枚举常量用于约定 payload 内容的编码规范uint8 MAV_TUNNEL_PAYLOAD_TYPE_UNKNOWN 0 # Encoding of payload unknown uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED0 200 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED1 201 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED2 202 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED3 203 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED4 204 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED5 205 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED6 206 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED7 207 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED8 208 # Registered for STorM32 gimbal controller uint8 MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED9 209 # Registered for STorM32 gimbal controller常量值一览常量名值用途MAV_TUNNEL_PAYLOAD_TYPE_UNKNOWN0payload 编码未知默认值MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED0200为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED1201为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED2202为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED3203为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED4204为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED5205为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED6206为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED7207为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED8208为 STorM32 云台控制器保留MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED9209为 STorM32 云台控制器保留类型注册规则的实践含义 32768注册区需要把新类型添加到MAV_TUNNEL_PAYLOAD_TYPE枚举中并提交到 PX4 主仓库供所有厂商共用≥ 32768实验区留给软件开发者做本地实验不应提交到广泛分发的代码库避免枚举空间被未协调的类型号污染。从源码实际使用看PX4 内部还使用了几类未写入本消息枚举、而是由 MAVLink 库定义的类型MAV_TUNNEL_PAYLOAD_TYPE_MODALAI_ESC_UART_PASSTHRU与MAV_TUNNEL_PAYLOAD_TYPE_MODALAI_IO_UART_PASSTHRU见 mavlink_receiver.cpp它们分别触发esc_serial_passthru与io_serial_passthru主题的转发是当前仓库中别名主题真正被使用的证据。数据通路一MAVLink 接收端如何解析并分流隧道数据的入口是 MAVLink 接收模块。在 mavlink_receiver.cpp 的handle_message_tunnel()中处理流程如下解码调用mavlink_msg_tunnel_decode()将原始 MAVLink 报文解码为mavlink_tunnel_t目标过滤调用evaluate_target_ok()检查target_system/target_component是否指向本机。注释明确指出payload 会被转发到真实设备若目标指向同一链路上的另一架飞行器绝不能写入本机的总线mavlink_receiver.cpp长度校验若payload_length sizeof(payload)即超过 128 字节直接丢弃消息。源码注释解释payload 缓冲区固定 128 字节而payload_length是uint8_t发送方可能宣称携带超过报文实际容量的数据此时宁可丢弃也不做截断因为透传消费者会把载荷原样转发到 UART截断帧会破坏设备协议mavlink_receiver.cpp填充 uORB 消息将时间戳、类型、目标、长度与载荷拷贝到mavlink_tunnel_s tunnel{}并通过static_assert在编译期保证tunnel.payload与 MAVLink 结构体 payload 尺寸一致mavlink_receiver.cpp按类型分流发布mavlink_receiver.cppswitch (mavlink_tunnel.payload_type) { case MAV_TUNNEL_PAYLOAD_TYPE_MODALAI_ESC_UART_PASSTHRU: _esc_serial_passthru_pub.publish(tunnel); break; case MAV_TUNNEL_PAYLOAD_TYPE_MODALAI_IO_UART_PASSTHRU: _io_serial_passthru_pub.publish(tunnel); break; default: _mavlink_tunnel_pub.publish(tunnel); break; }对应的三个 uORB 发布器声明在 mavlink_receiver.huORB::Publicationmavlink_tunnel_s _mavlink_tunnel_pub{ORB_ID(mavlink_tunnel)}; uORB::Publicationmavlink_tunnel_s _esc_serial_passthru_pub{ORB_ID(esc_serial_passthru)}; uORB::Publicationmavlink_tunnel_s _io_serial_passthru_pub{ORB_ID(io_serial_passthru)};也就是说同一份解码后的数据根据payload_type决定进入哪个主题未知类型一律走通用的mavlink_tunnel主题。消息处理入口在MavlinkReceiver::handle_message()的case MAVLINK_MSG_ID_TUNNEL:处注册mavlink_receiver.cpp。数据通路二驱动侧订阅并写入外设 UART隧道数据的出口是订阅对应主题的驱动。仓库中两处真实消费端VOXL ESC 电调透传voxl_esc.cppuint8_t num_writes 0; // Dont do these faster than 20Hz if (hrt_elapsed_time(_last_uart_passthru) 50_ms) { _last_uart_passthru hrt_absolute_time(); // Dont do more than a few writes each check while (_esc_serial_passthru_sub.updated() (num_writes 4)) { mavlink_tunnel_s uart_passthru{}; _esc_serial_passthru_sub.copy(uart_passthru); if (_uart_port.write(uart_passthru.payload, uart_passthru.payload_length) ! uart_passthru.payload_length) { PX4_ERR(Failed to send mavlink tunnel data to esc); return false; } num_writes; } }实现要点订阅esc_serial_passthru主题每次周期最多处理 4 条消息num_writes 4避免突发数据阻塞控制回路透传频率被限制在 20 Hzhrt_elapsed_time(...) 50_ms防止隧道数据淹没串口写入串口时只发送payload_length指定的字节数而不是整个 128 字节缓冲区保证外设只收到有效数据写入长度不符时打印PX4_ERR(Failed to send mavlink tunnel data to esc)并返回失败。VOXL2 I/O 协处理器透传voxl2_io.cpp采用完全相同的模式订阅io_serial_passthru主题将payload与payload_length写入 I/O 串口。这两个驱动文件分别位于 src/drivers/actuators/voxl_esc/ 与 src/drivers/voxl2_io/可以对照阅读确认调用细节。日志记录与可观测性MavlinkTunnel 主题还被纳入了 PX4 的日志系统。在 logged_topics.cpp 中LoggedTopics::add_mavlink_tunnel()通过add_topic(mavlink_tunnel)将通用隧道主题注册为可记录的 topic随后在日志主题清单构建时被加入logged_topics.cpp。这意味着默认日志配置下mavlink_tunnel的收发记录会被写入 ulog便于事后分析隧道流量而esc_serial_passthru/io_serial_passthru是否记录则取决于具体板卡的日志配置。自定义 payload 类型的接入步骤如果你要在自己的项目里复用这套隧道机制从上述源码可以总结出完整接入路径注册类型号若使用小于 32768 的类型号在 msg/MavlinkTunnel.msg 的枚举区追加常量并提交回 PX4 主仓库仅做本地实验则选用 32768 以上的号段发送端地面站/上位机发送MAV_TUNNEL报文填写payload_type、target_system、target_component、payload_length与payload接收端在 mavlink_receiver.cpp 的switch中新增case将消息发布到你自定义的主题或复用mavlink_tunnel通用主题消费端驱动中订阅对应主题参照 voxl_esc.cpp 的模式按payload_length将payload写入目标串口并注意节流20 Hz与限流每周期最多若干条以保护外设链路。小结MavlinkTunnel 是 PX4 中连接 MAVLink 网络与板载串口设备的透明管道MAV_TUNNEL_PAYLOAD_TYPE枚举负责约定载荷编码规则TOPICS别名把同一消息类型按载荷类型分流到mavlink_tunnel、esc_serial_passthru、io_serial_passthru三个主题接收端mavlink_receiver.cpp负责解码、目标过滤、长度校验与分流发布消费端voxl_esc.cpp 与 voxl2_io.cpp负责把载荷写入外设 UART。理解这条通路即可安全地扩展自己的串口透传场景。赞分享嵌入式物联网机器人自动驾驶智能硬件【免费下载链接】PX4-AutopilotPX4 Autopilot Software项目地址https://gitcode.com/gh_mirrors/px/PX4-Autopilot点击查看免费下载相关推荐PX4-Autopilot 中的 DebugValue UORB 消息定义、发布、MAVLink 透传与飞行日志调试实战PX4 Autopilot 中的 DebugValue UORB 消息定义、发布、MAVLink 透传与飞行日志调试实战 DebugValue 是 PX4 飞嵌入式物联网机器人自动驾驶智能硬件PX4 DebugArray UORB 消息详解从字段定义到 Mavlink 调试链路实战PX4 DebugArray UORB 消息详解从字段定义到 Mavlink 调试链路实战 PX4 的 debug_array 是一类专用于批量浮点调试数据的嵌入式物联网机器人自动驾驶智能硬件5款免费开源网络拓扑工具从手画到自动更新拓扑5款免费开源网络拓扑工具从手画到自动更新拓扑 网络变更前夜你要向客户讲清故障路径翻遍共享盘只找到半年前的旧拓扑图——这种窘境很常见。开源项目 Awesom嵌入式物联网机器人自动驾驶智能硬件上一篇Sails 模型属性Attributes完全指南类型安全、校验、列映射与自动迁移下一篇JupyterLab 项目推荐创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考