MAVLink 底层架构与运行逻辑
MAVLink 底层架构与运行逻辑
MAVLink 底层架构与运行逻辑
MAVLink 是面向无人系统设计的轻量级消息协议,广泛应用于飞控、地面站、机载外设等设备间通信。参考官方设计规范,本文从底层架构、组件构成、消息流转、通信模式、运行规则等维度,梳理其整体工作逻辑,聚焦协议架构与交互机制
一、MAVLink 整体架构体系
MAVLink 采用模块化、分层式架构设计,整体实现协议逻辑与传输介质解耦,可灵活适配串口、以太网、无线链路、CAN 总线等多种传输通道。整套架构主要分为协议核心层、传输适配层、设备交互层三大部分,各层级职责清晰、单向依赖,保障协议的轻量化与跨平台能力。
1.1 层级划分与核心职责
1.1.1 设备交互层
该层面向业务应用与终端设备,是开发者和上层业务的直接交互入口。
负责设备状态上报、飞行指令下发、参数读写、任务调度、事件通知等业务行为。上层应用仅需调用标准化接口发起交互,无需感知底层协议规则与传输方式,实现业务逻辑与通信底层隔离。所有飞控、地面站、外设的业务交互行为,均基于该层完成触发与响应。
1.1.2 协议核心层
作为 MAVLink 的中枢核心,承载整套协议的规则定义与逻辑调度,也是架构中最关键的部分。
主要包含消息定义、命令规范、系统组件标识、交互规则、会话管理、状态同步等模块。该层统一约束消息类型、交互时序、应答逻辑、设备寻址规则,定义不同终端之间的通信语义,是多厂商、多设备互联互通的基础。同时负责消息路由、优先级管理、交互状态维护,保障通信过程有序执行。
1.1.3 传输适配层
承担协议核心与物理链路的衔接工作,核心目标是屏蔽不同传输通道的差异。
MAVLink 本身不绑定专属传输协议,该层对串口、TCP/UDP、无线数传、CAN 等链路进行统一封装,向上层协议核心提供标准的数据收发接口。更换物理传输方式时,仅需调整适配层配置,协议核心与上层业务无需改动,具备极强的可移植性。
1.2 架构设计核心特性
- 轻量化设计:架构摒弃复杂会话与冗余逻辑,代码体积小、资源占用低,可在资源受限的嵌入式飞控上稳定运行。
- 去中心化通信:采用对等通信架构,无中心服务节点,任意接入网络的设备均可按照规则收发消息、发起交互。
- 跨链路兼容:传输层完全解耦,支持有线、无线、局域网络等多种主流无人系统传输介质。
- 可扩展能力:协议层预留自定义消息、自定义命令接口,可根据业务需求拓展通信内容。
二、MAVLink 版本
MAVLink 主流分为 v1.0 和 v2.0 两个可用版本,另有已淘汰的预发布版 v0.9。其中 v2.0 为当前官方推荐版本,且开发库向下兼容 v1.0,可同时解析两类协议报文。
2.1 各版本概况
- MAVLink 2.0:2017 年起大规模普及,功能更强、安全性更高,是新设备首选。
- MAVLink v1.0:2013 年广泛应用,目前仍大量搭载在传统老旧外设上。
MAVLink v0.9:早期测试版本,2018 年已彻底停止维护,仅部分历史代码中存在残留,实际使用中基本不会接触。
2.2 版本识别方法
在抓包分析或设备调试中,可通过以下三种方式快速判定 MAVLink 协议版本:
| 识别方式 | 说明 | 示例/备注 |
|---|---|---|
| 报文起始标记(最直观) | 数据包首字节直接区分主版本 | MAVLink 1: 0xFEMAVLink 2: 0xFD不支持该版本的库无法识别此标记 |
| 能力标志校验 | 通过 AUTOPILOT_VERSION 消息判断设备是否支持 v2.0 |
读取 capabilities 字段,检查 MAV_PROTOCOL_CAPABILITY_MAVLINK2 标志位 |
| 次版本号查询 | 通过 HEARTBEAT 消息获取协议次版本号 |
mavlink_version 字段,对应 common.xml 中定义的消息集版本 |
补充说明:消息体本身不携带版本信息,协议通过
CRC_EXTRA校验机制,确保收发双方使用的消息定义完全兼容。
2.3 版本握手与链路适配
设备依靠版本标记、能力标志即可完成基础版本识别,不同通信链路的适配规则有所区别:
-
透明链路
飞控与地面站之间数据完整转发,仅依靠上述识别方式即可正常通信,目前绝大多数链路都属于此类。 -
非透明链路
存在路由转发、数据重组,或是老旧无线数传采用固定分包,容易破坏 v2.0 可变长报文。
可通过指令交互完成严谨校验:地面站发送指定指令,请求一条 v2.0 专属消息。对方正常回传则代表支持 v2.0;返回否定应答即为不支持;无响应则判定通信超时。
注:旧版检测消息
PROTOCOL_VERSION现已废弃。
- 半透明链路
以 SiK 系列数传电台为代表,会主动向数据流中插入状态消息。这类设备在收到第一条 v2.0 报文后,会以 v2.0 格式发送状态消息,以此证明协议兼容性。
2.3.1 版本握手时序流程

流程说明:
- GCS 发起校验:发送
MAV_CMD_REQUEST_MESSAGE指令,param1 填入 MAVLink 2 专属消息ID(>256)。 - 飞控响应:支持 v2.0 则返回 v2 格式消息;不支持则返回 NACK;无响应则超时。
- 版本切换:GCS 收到 v2 消息后,双方正式切换到 MAVLink 2.0 通信。
作用:解决电台/路由导致的非透明链路问题,确保 v2.0 能稳定运行。
2.4 版本与签名的通道约束
MAVLink 以独立通信通道(串口、UDP 等)为单位绑定协议版本:
- 单条通道内所有设备必须使用同一协议版本,不能混用 v1.0 与 v2.0。
- 若开启 v2.0 消息签名功能,同通道设备还需使用统一密钥。
- 实际组网中,老旧外设(v1.0)、普通 v2.0 设备、带签名的 v2.0 设备,建议划分不同通道分别对接。
2.5 版本协商通用规则
为兼顾新特性与老旧设备,设备默认支持双版本自适应,核心规则如下:
- 飞控支持按通道单独开关 v2.0 功能,配置生效通常需要重启设备。
- 开启消息签名后,设备上电直接发送带签名的 v2.0 报文。
- 未开启签名时,设备可先发 v1.0 报文,检测到链路中存在 v2.0 数据后自动切换版本。
- 支持 v2.0 的设备,需在能力标志位中明确标识自身兼容性。
- 地面站可手动指定协议版本,也可自动探测对端设备能力、完成版本匹配。
三、MAVLink 2
MAVLink 2 是协议的升级版本,具备向下兼容性,同时大幅提升了通信灵活性与安全性。目前官方已提供 C、C++11、Python 语言对应的开发库。
3.1 核心新特性
-
24位消息ID
MAVLink 1 仅支持 256 类消息,MAVLink 2 支持超 1600 万种自定义消息,拓展能力大幅提升。 -
数据包签名
用于校验消息来源,确保数据由可信设备发出,强化通信安全。 -
消息扩展
可在已有消息内新增字段,未升级的旧设备依旧可以正常解析,不破坏二进制兼容性。 -
载荷空字节截断
发送前自动移除载荷末尾的零值空字节,减少传输数据量;MAVLink 1 会完整传输所有字节。 -
兼容/非兼容标志位
用于协议迭代演进:无法识别非兼容标志则直接丢弃数据包;无法识别兼容标志,仍可正常处理报文。
3.2 版本升级说明
- 版本协商:链路两端的版本探测与协商规则
- C 语言库:MAVLink 2 的 C 语言库原生兼容 MAVLink 1,库升级、新旧版本混用配置可参考
mavgen工具文档。
四、MAVLink2 消息签名机制
MAVLink 2 增加了消息签名能力,主要用来验证通信报文确实来自合法、可信的设备。
4.1 报文帧格式
启用签名的报文,会将头部不兼容标志位的 0x01 位置1,并在报文尾部额外追加 13 字节 的签名字段。
补充说明
报文头部的不兼容标志位遵循如下规则:若 MAVLink 库无法识别或处理该标志位,必须直接丢弃对应报文。也就是说,不支持签名功能的 MAVLink 库,会拒收所有已签名报文。在 C 语言库中,通过宏MAVLINK_IFLAG_SIGNED定义该签名标识位。

13字节签名字段说明
| 字段 | 位数 | 说明 |
|---|---|---|
| linkID (8 bits) | 8位 | 报文所属通信链路ID,通常与通信通道编号一致 |
| timestamp (48 bits) | 48位 | 时间戳。以10 微秒为单位,计时起点为格林威治时间2015年1月1日。同一条链路中,该数值必须单调递增。若报文平均速率超过10万包/秒,时间戳数值会快于实际物理时间 |
| signature (48 bits) | 48位 | 48位签名值,基于完整报文、时间戳与密钥计算得到 |
4.2 链路ID、签名算法与时间戳规则
4.2.1 链路ID
链路ID为固定8位数据,核心作用是隔离多通信链路,保证MAVLink多链路组网场景下,消息签名、时间戳校验机制正常工作,避免不同通道数据互相干扰。
在实际部署中,一台飞控或地面站往往会同时启用多条通信通道,比如USB有线、Wi-Fi无线、远距离数传电台等,不同链路的传输时延、丢包率、传输速率差异极大。设备需要为每一条已启用的物理/逻辑通信通道分配唯一链路ID,并在发送签名报文时填充至对应字段。尤其在Wi-Fi搭配数传电台这类时延差距明显的组合场景中,链路ID是区分数据流、防止校验误判的关键。
协议定义系统ID, 组件ID, 链路ID三元组为一条独立逻辑数据流。时间戳单调递增、时序校验、签名状态维护等所有规则,均以单条逻辑数据流为单位独立执行。简单来说,不同链路、不同设备组件的数据流相互隔离,一条链路的报文时序异常,不会影响其他链路的正常通信。
补充:链路ID的底层处理逻辑可查阅官方文档《C Message Signing > Handling Link IDs》。
4.2.2 签名计算规则
签名是校验报文完整性与设备身份的核心,采用 SHA-256 哈希算法 生成,最终输出48位(6字节)签名值。
签名依赖的密钥为固定32字节二进制数据,属于整个签名体系的安全根基。所有需要互相通信的设备(飞控、地面站、机载外设等)必须配置完全一致的密钥,否则签名校验必然失败。该密钥由通信双方私下约定,严禁对外公开。
(1) 计算逻辑与数据源说明
签名的计算范围不包含报文尾部13字节签名字段,仅组合密钥、原始报文主体、链路ID与时间戳进行运算。运算规则:将所有数据按顺序拼接,对拼接结果执行SHA-256哈希,截取哈希结果的前48位作为最终签名。
数据流转过程:
secret_key + header + payload + CRC + link-ID + timestamp
↓ 二进制数据拼接
↓ 执行 SHA-256 哈希运算
256位哈希结果
↓ 截取前48位
最终 signature 签名值
公式中 + 代表二进制数据拼接,sha256_48() 指代截取SHA-256结果前48位的运算逻辑:
signature = sha256_48(secret_key + header + payload + CRC + link-ID + timestamp)
(2) 参与签名计算的数据源明细
| 字段名称 | 数据长度 | 字段说明 |
|---|---|---|
| secret_key | 32 字节 | 通信密钥,通信双方必须保持一致 |
| header | 可变 | MAVLink 2 标准报文头部 |
| payload | 可变 | 报文有效载荷,承载业务数据 |
| CRC | 可变 | 报文校验和 |
| link-ID | 8 位(1 字节) | 通信链路标识 |
| timestamp | 48 位(6 字节) | 时序戳,用于防重放攻击 |
只要上述任意一部分数据被篡改、密钥不匹配、链路ID或时间戳异常,都会导致本地计算出的签名与报文携带签名不一致,以此实现防篡改、防伪造的安全能力。
4.2.3 时间戳管理规则
时间戳主要用来防止重放攻击。简单说就是避免攻击者截取旧报文反复发送、冒充正常数据。协议对时间戳的计时方式、使用、校验都做了统一规定。
(1) 基础定义与时间换算
时间戳单位为 10 微秒,统一从 格林威治时间 2015年1月1日 开始计算。
如果设备使用常规Unix时间(从1970年1月1日算起),可以加上固定偏移值 1420070400 秒完成换算。
受设备时钟、GPS信号等影响,报文里的时间戳不一定和标准时间完全一致,协议对此不作强制要求,只要求先后顺序正常。
规定:在同一组
(系统ID, 组件ID, 链路ID)的通信链路中,后一条报文的时间戳必须比前一条大。如果报文发送速度极快(每秒超10万条),时间戳数值会比真实时间走得更快,这属于正常情况。
(2) 设备本地时间戳使用规则
飞控这类嵌入式设备经常出现断电丢时间、开机没定位GPS、没有硬件时钟等问题,因此统一按以下规则维护时间戳:
- 定时保存
定期把当前时间戳保存到断电不丢失的存储区域,建议至少每分钟存一次,防止重启后时序错乱。 - 开机取值
设备开机后,对比系统算出的时间戳和之前保存的历史时间戳,取更大的那个作为初始时间,保证时间不会倒流。 - GPS 对时
没有硬件时钟的设备,成功搜到GPS信号后,对比GPS时间戳和本地当前值,同样取较大值更新。 - 发包自增
每发送一条签名报文,对应链路的时间戳自动加1,确保顺序递增。 - 合法报文同步时间
收到校验正常的报文时,如果对方时间戳比本地大,就更新本地时间,实现两端时间对齐。
重要提醒:哪怕设备选择收下签名异常的报文,也绝对不能用这类报文的时间戳更新本地时间,防止被恶意数据干扰。
(3) 接收报文的校验规则
收到签名报文后,会根据对方的链路ID、系统ID、组件ID做两道检查,不满足则直接丢弃报文:
- 对比历史记录,如果新报文时间戳比上一条更小,说明是重复旧数据,直接拒收。
- 若是第一次收到该设备报文,当对方时间戳比本地时间落后超过1分钟,也判定为过期数据,予以拒收。
(4) 高并发场景优化
报文收发频繁、频繁读写存储时,容易出现数据错乱。推荐做法:
在存储里同时保存两份时间戳。写入数据时更新偏小的那一组,读取数据时使用偏大的那一组,以此避免并发读写引发异常。
4.3 报文接收与放行规则
MAVLink 依据已签名报文、未签名报文、签名异常报文三类数据,执行差异化接收策略,在保障通信安全的同时,适配调试、兼容等实际使用场景。
4.3.1 已签名报文接收规则
针对已完成签名的报文,出现以下任意一种情况,设备将直接丢弃该报文:
- 时序倒退
在同一个逻辑数据流(由系统ID、组件ID、链路ID三元组标识)中,新报文的timestamp小于此前接收报文的时间戳。例如上一帧报文时间戳为 2000,新报文为 1980,判定为重复旧数据,直接拒收。 - 签名校验不通过
设备本地运算得到的 48 位signature,与报文携带的签名值不一致,代表数据被篡改或两端secret_key不匹配。 - 报文超时
报文timestamp相比设备本地时间,滞后超过 600 万单位(1 分钟),判定为过期数据并拒收。
4.3.2 未签名报文放行规则
MAVLink 库支持自定义策略,有条件地接收未签名报文,可结合设备参数、传输链路、报文类型、协议标志位灵活配置。
说明:未满足放行规则的未签名报文必须全部拦截,否则消息签名的安全机制将失效。
典型应用场景:
- 通过设备参数全局配置,允许接收所有未签名报文,多用于设备调试阶段;
- 针对 USB、有线以太网这类安全通道,默认放行未签名报文;
- 通信状态类报文
RADIO_STATUS固定免签名接收,保障数传电台正常工作; - 搭配硬件按键触发临时模式,开机长按按键后,设备可接收所有未签名报文;
- 设备上电初期兼容未签名报文,一旦收到第一条合法已签名报文,自动切换为严格校验模式。
4.3.3 签名异常报文处理规则
系统可按需开启放行签名异常报文的功能,主要用于应急排查场景。
举例:飞行器密钥损坏、设备失联时,地面站可临时放行签名异常报文,正常解析位置等基础数据,辅助找回设备。
重要规范:若开启该功能,设备必须做出醒目提示,标注当前连接存在安全风险。签名异常一般由配置错误、传输故障、协议异常导致,也可能是受到恶意攻击。
4.4 密钥管理与日志安全规范
密钥是MAVLink签名体系的信任根基,其全生命周期管理与日志脱敏策略,是防范密钥泄露、离线破解等攻击的关键环节。
4.4.1 密钥管理规则
通信密钥固定为32字节二进制数据,组网内所有交互设备必须配置相同密钥,签名校验才能正常生效。密钥通常由地面站统一生成并分发至各终端设备。
(1)密钥生成方式
密钥的生成逻辑由设备自主实现,主流方案分为两种,均可输出符合标准的32字节密钥:
- 将用户手动输入的字符串,经过 SHA-256 哈希运算转换为密钥;
- 调用随机密钥生成器,直接生成随机二进制密钥。
(2)密钥使用限制说明
补充说明
官方 mavgen C、Python 库默认单链路仅支持配置单个密钥,该限制属于程序实现问题,并非协议强制要求。实际开发中可拓展设计密钥池,或是为每一条通信连接单独分配密钥。
(3)密钥存储要求
密钥必须存入设备持久化存储区域,全程严格保密。禁止通过各类通信协议对外传输,同时不得在MAVLink参数、运行日志、数据闪存日志中留存,避免密钥明文泄露。
(4)密钥分发与重置
设备通过 SETUP_SIGNING 报文完成密钥的配置与重置,执行规则如下:
- 该报文仅允许在USB、本地串口等有线安全链路中,以单播形式定向发送至指定
系统ID与组件ID,接收设备解析后将密钥存入持久化存储; - 密钥重置与初次配置采用同一套安全流程,安全标准保持一致;
- 禁止广播
SETUP_SIGNING报文,同时也不允许自动转发该报文,防止密钥从安全链路流转至Wi-Fi等无线不安全链路造成泄密; - 未搭载USB通信功能的飞控设备,可通过NSH Shell等命令行界面本地设置密钥。
实用建议
推荐由地面站统一生成密钥并通过有线通道下发。可临时关闭安全通道的签名校验功能,即便密钥丢失或损坏,也能正常完成重新配置。
4.4.2 日志安全处理规则
日志中若留存密钥、原始签名数据,会被攻击者利用开展离线分析、暴力破解,因此必须做脱敏处理。
| 处理对象 | 处理规则 | 安全作用 |
|---|---|---|
| SETUP_SIGNING 报文 | 日志中直接剔除该报文;若需保留记录,将密钥字段替换为32字节 0xFF |
彻底规避密钥明文泄露风险 |
| 已签名报文 | 清除报文签名标志位,并移除尾部13字节签名字段 | 减少签名样本泄露,提升离线攻击难度 |
4.5 参考
本文相关规则均参考官方《Message Signing Proposal》文档,该文档还详细阐述了签名机制的设计思路、抗重放攻击、抗离线攻击等安全能力评估内容,可作为深度研究资料。
五、MAVLink 数据包序列化与帧结构
数据包序列化,就是把设备要传输的各类数据,转换成统一的二进制格式在通信链路上传递。MAVLink 的数据包格式参考了车载通信相关标准设计,同时借助 CRC_EXTRA 校验位,保证发送方和接收方对数据格式的理解完全一致。
日常使用无人机相关设备时,数据的编码、解码工作都由官方函数库自动完成,使用者不用深究底层格式;本节内容主要面向协议开发、工具维护相关的开发人员。
MAVLink 传输多字节数据时,统一采用小端序规则排布字节,官方函数库也默认适配主流的小端架构硬件。
简单解释:
- 字节序(大小端)
计算机里一个数字常会用多个字节存储/传输,字节序规定了高低字节的排列顺序。
- 小端序:低位字节放前面,高位字节放后面(先传低字节、后传高字节)。
举个例子:数字0x1234占2个字节,小端传输顺序为0x34→0x12。- 对应的大端序:高位字节在前,低位字节在后,和日常书写数字习惯一致。
MAVLink 网络传输固定用小端序,收发双方必须按这个规则解析,否则读出的数据会出错。
- 小端架构硬件
指CPU、单片机等硬件,原生默认使用小端序存储数据。
现在绝大多数电脑、无人机飞控、嵌入式芯片都是小端架构,和MAVLink传输规则天然匹配,不用额外做字节转换。
5.1 MAVLink 2 数据包格式
MAVLink 2 是目前应用最广泛的版本,额外增加了可选的签名字段,通信安全性和兼容性更强,链路传输的完整结构如下:

数据包传输顺序:magic(STX) + len + incompat_flags + compat_flags + seq + sysid + compid + msgid + payload + checksum + signature
数据包起始标志 + 有效载荷长度 + 不兼容标志 + 兼容标志 + 数据包序号 + 发送系统 ID + 发送组件 ID + 消息类型 ID + 业务数据载荷 + CRC 校验和 + 可选签名字段
| 字节索引 | C 语言类型 | 字段名称 | 取值范围 | 功能说明 |
|---|---|---|---|---|
| 0 | uint8_t | magic(STX) | 0xFD(固定值) | 数据包起始标志,收到该数值就代表这是一条 MAVLink 2 数据。不支持该版本协议的设备,会直接丢弃这条数据 |
| 1 | uint8_t | len | 0~255 | 标识后续业务数据的字节长度,支持对过长数据做截断处理 |
| 2 | uint8_t | incompat_flags | — | 强制兼容标志。设备无法识别该标志时,必须丢弃当前数据包 |
| 3 | uint8_t | compat_flags | — | 可选兼容标志。设备不认识该标志,也能正常解析使用数据包 |
| 4 | uint8_t | seq | 0~255 | 数据包编号。每发送一条数据编号加一,用于判断传输过程中是否丢包 |
| 5 | uint8_t | sysid | 1~255 | 发送设备编号,区分网络里多台无人机,不能使用编号0 |
| 6 | uint8_t | compid | 1~255 | 设备内部模块编号,区分同一台无人机里的飞控、摄像头等部件,禁止使用广播编号 |
| 7~9 | uint32_t | msgid(24位) | 0~16777215 | 消息类型编号,根据这个编号解析后续业务数据的含义 |
| 10 ~ 9+n | uint8_t | payload | 0~255 字节 | 核心业务数据,存储无人机位置、姿态、指令等信息,单包最大255字节,n为当前数据的字节数 |
| n+10 ~ n+11 | uint16_t | checksum | CRC-16/MCRF4XX值 | 校验码,检查数据在传输中是否出错,校验范围不包含起始标志位 |
| n+12 ~ n+25 | uint8_t | signature[13] | 13字节(可选) | 可选签名字段,开启后可验证数据是否被篡改,提升通信安全 |
数据包长度由业务数据和签名功能共同决定,具体分为两种情况:
-
最短长度(12 字节)
载荷区无业务数据(payload = 0字节),且不启用签名字段。此时仅保留协议基础结构,多用于应答、确认类报文,只做通信回执,不传输飞行指令、设备状态等数据。 -
最长长度(280 字节)
载荷区填满 255 字节最大业务数据,同时开启 13 字节签名字段。可完整传输无人机状态、任务指令、图像等信息,借助签名实现数据防篡改。
小结:12 字节 = 空数据包 + 无签名;280 字节 = 满载数据 + 启用签名。
5.2 MAVLink 1 数据包格式
MAVLink 1 是早期版本,结构更加简单,不支持数据签名功能,整体包长更短,具体格式如下:

数据包传输顺序:magic + len + seq + sysid + compid + msgid + payload + checksum
数据包起始标志 + 有效载荷长度 + 数据包序号 + 发送系统 ID + 发送组件 ID + 消息类型 ID + 业务数据载荷 + CRC 校验和
| 字节索引 | C 语言类型 | 字段名称 | 取值范围 | 功能说明 |
|---|---|---|---|---|
| 0 | uint8_t | magic | 0xFE(固定值) | 数据包起始标志,用于识别这是 MAVLink 1 格式数据 |
| 1 | uint8_t | len | 0~255 | 标识后续业务数据的长度,同一种类消息的数据长度固定不变 |
| 2 | uint8_t | seq | 0~255 | 数据包编号,逐包递增,用于检测传输丢包 |
| 3 | uint8_t | sysid | 1~255 | 发送设备编号,区分组网内不同无人机,不可使用编号0 |
| 4 | uint8_t | compid | 1~255 | 设备内部模块编号,区分飞控、云台等部件,禁止使用广播编号 |
| 5 | uint8_t | msgid | 0~255 | 消息类型编号,用来解析后续业务数据 |
| 6 ~ 5+n | uint8_t | payload | 0~255 字节 | 业务数据区域,存放各类飞行、设备信息,单包最大255字节,n为当前数据的字节数 |
| n+6 ~ n+7 | uint16_t | checksum | CRC-16/MCRF4XX值 | CRC-16 校验码,排查传输错误,计算范围不含起始标志位 |
数据包长度由业务数据容量决定,具体分为两种情况:
-
最短长度(8 字节)
载荷区无业务数据(payload = 0字节),仅保留协议基础结构。这类数据包多为应答、确认类报文,只做通信回执,不传输飞行指令、设备状态等数据。 -
最长长度(263 字节)
载荷区填满 255 字节最大业务数据,可完整传输无人机状态、任务指令等各类信息。
小结:8 字节 = 空数据包;263 字节 = 满载数据。
5.3 MAVLink 2 标志位详解
MAVLink 2 在协议头部新增了两类标志位:不兼容标志与兼容标志,专门用于扩展协议功能,二者的作用、安全规则完全不同。
5.3.1 不兼容标志(Incompatibility Flags)
不兼容标志用于标记会改变数据包格式/结构的核心功能。
如果接收设备不认识其中任何一个标志,必须直接丢弃整个数据包,无法继续解析。
| 标志值 | C 语言宏定义 | 功能说明 |
|---|---|---|
| 0x01 | MAVLINK_IFLAG_SIGNED | 数据包已启用签名,尾部附加了13字节安全签名 |
这是强制性要求。设备必须支持该功能才能收包,否则直接拒收。
最常用场景:开启数据包签名,确保数据不被篡改。
5.3.2 兼容标志(Compatibility Flags)
兼容标志用于标记不影响数据包格式的附加功能。
即使设备不认识这些标志,也可以直接忽略,仍然能正常解析数据包。
这是可选附加信息。比如标记“高优先级”,只做提示作用,不影响收包、解析核心数据。
5.4 有效载荷格式
MAVLink 为减少传输开销,有效载荷不附带消息结构信息,通信双方需预先统一字段规则。消息类型由msgid标识,飞行指令、遥测数据等内容均存放在有效载荷内。
协议会对载荷字段按数据长度从大到小重排序,提升传输与解析效率。MAVLink 2 可截断载荷末尾空字节并更新长度字段以节省带宽,MAVLink 1 则完整传输全部字节。
数据包采用 2 字节 CRC-16/MCRF4XX 校验和,校验范围不含起始字节与签名,同时纳入CRC_EXTRA字节,校验收发双方消息定义是否一致。
数据包一旦遭到篡改、伪造,或是格式不兼容,就会触发校验失败并被丢弃。该特性可用于识别异常报文,为无人机通信检测与防护提供支撑。
六、MAVLink 消息路由机制
MAVLink 网络由多类独立设备系统组成,单台系统又可划分为多个功能组件,协议通过标准化的寻址与转发规则实现全网消息交互。日常应用中,路由解析与转发逻辑均由官方函数库自动执行,本节主要阐述网络架构、寻址规则、通用路由判定逻辑,以及ArduPilot飞控固件中的具体实现机制,同时结合通信安全场景说明相关风险与应用要点。
6.1 网络架构与基础寻址
MAVLink 网络基本单元分为系统与组件两类。飞行器、地面站、天线跟踪器等独立设备为一个系统;单个系统内部包含自动驾驶仪、相机、舵机等不同功能组件。协议采用两级编号完成全网寻址,分别为系统ID与组件ID。
- 系统ID:在整个网络内唯一,取值范围为 1~255。自动驾驶仪默认系统ID为 1,网络中新增飞行器设备时,需分配连续且不重复的编号。地面站及开发接口通常选用编号区间高位数值(如 255),以此降低地址冲突概率,同时系统ID支持自定义配置,可满足多地面站协同组网需求。
- 组件ID:依据协议标准
MAV_COMPONENT统一分配,用于区分同一系统内部不同功能模块,实现设备内精准寻址。
消息通过有效载荷内两个 8 位字段指定接收对象:
target_system:指令待执行的目标系统target_component:指令待执行的目标组件,该字段依赖target_system,不可单独使用
若 target_system、target_component 字段省略或赋值为 0,当前消息即为广播消息,全网所有系统与组件都会接收并处理。依托定向寻址与广播模式,消息可灵活发送至指定单设备、设备内指定组件、单个系统全部组件或全网所有设备。
从通信安全角度来看,广播消息无访问限制,易被攻击者利用批量下发虚假遥测数据、恶意控制指令;定向报文则依赖合法ID寻址,伪造指令需匹配正确目标ID才能被设备响应。
6.2 通用路由判定规则
MAVLink 网络中,设备对收到的消息同时承担本地处理与转发中继双重角色,两类规则并行不悖:本地处理决定设备自身是否执行消息;转发规则决定消息是否扩散到其他链路。
6.2.1 本地处理条件
满足以下任意一条,设备必须本地处理该消息:
- 消息为广播消息(
target_system字段省略或为 0); target_system与自身系统ID匹配,且target_component为广播状态(省略或为 0);target_system、target_component均与自身完全匹配;target_system与自身系统ID匹配,且本地从未在任何链路中接收过该组<target_system, target_component>报文。
6.2.2 消息转发条件
满足以下任意一条,设备必须将消息转发至其他通信链路:
- 消息为广播消息(
target_system字段省略或为 0),转发至除来源链路外所有链路; target_system与自身系统ID不匹配,且设备已知目标系统对应的通信通道;target_system与自身系统ID匹配、指定了target_component字段,且设备曾在对应链路中监听到该<target_system, target_component>组合的报文。
本地处理条件 1:广播消息,设备自己要处理
只要是广播消息,设备都会解析、执行这条消息,比如更新心跳状态、响应广播指令。
→ 这是设备自身的行为。
转发条件 1:广播消息,设备要转发给其他链路
设备会把收到的广播消息,转发给除来源链路外的所有其他链路,让全网所有设备都能收到。
→ 这是设备作为中继的行为。
6.2.3 转发约束与补充规则
协议明确硬性约束:转发过程中严禁修改、重新封装原始数据包,必须完整转发原始报文内容。即便设备因权限、功能限制无法解析报文,或是无法完成签名校验,也需严格遵循路由规则执行转发。对于协议库不支持的未知消息,统一按照广播报文逻辑转发。
广播消息会转发至所有尚未接收该报文的通信通道;定向报文仅当设备曾在某一通道监听到目标设备数据时,才会在该通道进行转发,若目标地址未知、或报文来源于目标设备所在通道,则不执行转发操作。非广播类报文仅允许转发至已确认存在的目标地址。
6.3 ArduPilot 飞控路由实现
ArduPilot 飞控支持多遥测端口,可将单一端口收到的 MAVLink 消息,统一路由转发至其余所有遥测端口。该功能适用于飞控、机载辅助计算机等多组件共用一条无线遥测链路的场景,是无人机机载组网的核心能力。
6.3.1 核心工作流程
飞控通过 MAVLink_routing 类统一管理路由逻辑,工作流程如下:
- 抓取每条入站报文,提取报文自带的源
sysid(系统ID)与compid(组件ID); - 建立路由映射表,记录各个物理通道(USB、Telem1、Telem2 等)与
<sysid, compid>地址对的对应关系; - 解析报文的
target_system与target_component:若目标地址与本机地址不匹配,依据路由表转发至对应通道;无明确目标地址的报文,飞控完成本地处理后,广播转发至全网已知设备。
6.3.2 本地处理判定规则(飞控端)
当飞控收到消息时,满足以下任一条件则执行本地处理,处理动作不影响转发逻辑:
- 消息无
target_system字段; target_system字段值为 0(广播地址);- 目标系统ID为本机ID,且无
target_component字段; - 目标系统ID、目标组件ID均与本机完全匹配;
- 目标系统ID为本机ID,且飞控从未在任何链路中收到过该组
<target_system, target_component>报文。
6.3.3 消息转发判定规则(飞控端)
满足以下任一条件,飞控将报文转发至其他通信链路:
- 消息无
target_system字段; target_system字段值为 0(广播地址);- 目标系统非本机,且飞控已在对应链路中监测到该目标设备;
- 目标系统为本机、且指定了目标组件,同时飞控已在链路中监测到该组地址组合。
6.3.4 路由状态联动与协议约束
- 地面站交互约定:地面站仅在链路中收到目标设备报文后,才会向该
<sysid, compid>组合发送定向指令(如PARAM_SET),避免无效报文转发。 - 设备重启检测:飞控会持续监测
SYSTEM_TIME报文,若报文中time_boot_ms数值下降,判定对应设备发生重启,需立即清空本地路由记录表,适配设备重启后的网络状态。 - 转发行为约束:转发过程中严禁修改、重新封装原始数据包,必须完整转发原始报文内容,保障跨链路通信一致性。
6.4 不同版本与场景适配
6.4.1 协议版本差异
- MAVLink 1 未提供路由功能专用接口,无法直接解析
target_system与target_component,需通过通用接口读取有效载荷并手动匹配字段。 - MAVLink 2 优化了路由信息解析逻辑,在结构体
mavlink_msg_entry_t中增设标志位FLAG_HAVE_TARGET_SYSTEM、FLAG_HAVE_TARGET_COMPONENT,可快速判断报文是否携带寻址字段,并通过字段偏移量直接定位信息位置,适配复杂组网场景。 - 无签名 MAVLink 2 报文的路由行为与 MAVLink 1 完全一致,仅在启用签名时增加安全校验环节
6.4.2 签名报文路由规则
MAVLink 2 启用签名的安全报文,路由逻辑与普通报文保持一致,额外增加约束:转发时不得更改报文任意内容,包括原始签名数据。即使转发设备无法完成签名验证、无法解析报文,也必须按照标准规则转发,保障跨链路通信正常流转。
6.4.3 工程部署实现
工程应用中可使用 MAVLink Router 工具,实现串口、各类IP协议的混合组网,统一调度转发全网 MAVLink 流量,适配多链路、多设备的复杂组网场景。
6.5 安全关联分析
从通信安全角度来看,路由机制既是设备间协同的基础,也是潜在攻击入口:
- 广播报文无访问限制,易被攻击者利用批量下发虚假遥测数据、恶意控制指令;
- 定向报文依赖合法ID寻址,伪造指令需匹配正确目标ID才能被设备响应,可通过ID白名单实现基础访问控制;
- 转发过程严禁修改原始数据包,可将“转发报文被篡改”作为异常行为判定依据;
- 路由表清空机制可辅助监测设备异常重启、离线等状态,及时发现设备被恶意操控的迹象。
这些特性为无人机通信异常检测与指令防护策略提供了理论支撑,可基于路由规则设计针对性的安全防护方案。
七、MAVLink 路由增强与链路质量管理
在多链路、多设备的复杂组网场景下,基础路由机制会衍生出重复消息、链路质量评估等工程问题。本节介绍 MAVLink 体系中配套的冗余消息去重与数据包丢失计算机制,作为路由功能的重要补充。
7.1 冗余消息去重(Redundancy/Message De-duplication)
多链路广播转发场景下,同一设备可能通过多个通道收到完全相同的 MAVLink 报文,不仅会增加设备处理负载,还可能引发重复执行指令、状态更新混乱等问题。冗余消息去重机制正是为解决该问题设计。
7.1.1 实现原理
基于报文唯一标识过滤重复数据,核心标识字段组合为:
sysid(发送系统ID)compid(发送组件ID)msgid(消息类型ID)seq(数据包序列号)
设备维护本地缓存,记录最近一段时间内收到的报文唯一标识,若新接收报文的标识已存在于缓存中,则判定为重复消息,直接丢弃,不再处理与转发。
MAVLink 本身没有自带多信道去重功能,并且每条通信链路的数据包序号都是独立计数的,所以只靠序号没法区分不同链路发来的重复数据。
为降低重复指令带来的风险,协议里的控制指令都做了幂等设计。简单来说,同一指令多次下发,设备也不会出现异常操作,只会正常回复响应信息。
实际部署时,还会采用主备链路方案。日常只使用主链路传输数据,主链路中断后再切换到备用链路,从源头减少重复报文。像卫星通信这类延迟很高的链路,重复消息问题会更加明显,需要根据实际使用场景单独设计处理方案。
7.1.2 典型应用场景
- 飞控多遥测端口同时接收同一地面站广播报文
- 机载辅助计算机与飞控间多链路冗余通信
- 地面站多链路同时连接同一无人机系统
- 近距数传电台与远距离卫星链路并存的混合通信架构
7.2 数据包丢失计算(Packet Loss Calculation)
MAVLink 每个报文头部均包含 seq(数据包序列号)字段,发送设备会按递增顺序为每条报文分配序列号,接收设备可通过序列号的连续性,统计链路传输中的丢包情况。
7.2.1 计算方法
- 接收设备记录每个
(sysid, compid)对的当前最大序列号; - 对比新接收报文的序列号与历史最大值,若序列号出现跳变,则判定中间序号的报文丢失;
- 序列号为8位字段,计数达到255后会自动归零循环,接收端需兼容序号回绕的场景,避免误判丢包;
- 按时间窗口统计丢包数与总报文数,计算链路丢包率:
丢包率 = 丢失报文数 接收报文数 + 丢失报文数 × 100 % \text{丢包率} = \frac{\text{丢失报文数}}{\text{接收报文数} + \text{丢失报文数}} \times 100\% 丢包率=接收报文数+丢失报文数丢失报文数×100%
该统计方式仅适用于地面站与飞控直连的简单拓扑。在搭载机载计算机、路由转发或多冗余链路合并的复杂环境中,统计结果会出现偏差:路由设备会按需转发报文,未转发至统计端的报文会被误判为丢包;多条冗余链路合并传输时,各链路序列号相互独立,序号紊乱也会造成错误的丢包判定。
7.2.2 应用价值
- 实时评估无线遥测链路质量,为链路切换、功率调整提供依据;
- 辅助定位通信故障节点,判断丢包是发生在链路传输阶段还是设备转发阶段;
- 为地面站显示“信号质量”“链路稳定性”指标提供数据支撑。
7.3 机制协同与工程意义
冗余去重与丢包计算均依赖 MAVLink 报文的基础字段,两者协同工作可实现:
- 既避免重复消息对设备的干扰,又能精准评估链路质量;
- 为多链路冗余通信提供可靠的数据支撑,保障复杂组网场景下的通信稳定性;
- 不修改 MAVLink 协议标准,仅通过上层处理逻辑实现,兼容性强,可直接适配所有支持标准协议的设备。
结合协议原生特性来看,两类机制各有适用边界:消息去重需要配合幂等指令、主备链路等方案组合使用,才能适配全场景;丢包统计则更适合简单直连架构,复杂路由网络需额外优化统计逻辑,以此保障整体通信系统稳定可靠。
更多推荐


所有评论(0)