1. MAVLink协议基础:协议概述、消息格式、CRC校验原理
各位同学好,我是老张。做无人机地面站开发这些年,我最大的体会就是——MAVLink协议是绕不开的坎。你想想看,地面站和飞控之间怎么说话?靠的就是这个协议。今天咱们就把它的底裤扒干净。
1.1 协议概述:它到底是什么?
MAVLink,全称Micro Air Vehicle Link。说白了,就是一套轻量级的通信协议。专门给无人机、机器人这类嵌入式设备用的。我最早接触它是在2015年,那时候还在用v1.0版本,现在主流已经是v2.0了。
它的核心特点就三个:
- 轻量——消息体很小,一个心跳包才8个字节
- 可靠——有CRC校验,丢包重传机制
- 可扩展——你可以自定义消息,我就在项目里加过几条私有消息
嗯,这里要注意。MAVLink不是万能的。它适合串口、UDP、TCP这类链路。但如果你要用在蓝牙低功耗或者LoRa上,得自己掂量一下帧长。
1.2 消息格式:一个包长什么样?
咱们直接看v2.0的帧结构。我习惯把它拆成三部分:头部、负载、尾部。
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| STX | 1 | 起始标志,v2.0固定为0xFD |
| LEN | 1 | 负载长度,0-255 |
| SEQ | 1 | 序列号,用于检测丢包 |
| SYS ID | 1 | 系统ID,地面站通常为255 |
| COMP ID | 1 | 组件ID,比如飞控是1 |
| MSG ID | 3 | 消息ID,0-16777215 |
| Payload | 0-255 | 实际数据 |
| CRC | 2 | 校验码,包含整个包 |
你看,头部一共7个字节。MSG ID用了3个字节,这意味着v2.0支持超过1600万种消息类型。v1.0只有256种,这就是升级的原因之一。
我个人习惯在调试时先看SEQ字段。如果发现序列号跳变,那链路肯定有丢包。有一次客户说地面站经常断连,我一查日志,SEQ从100直接跳到150,中间丢了50个包。最后发现是串口波特率设错了。
1.3 CRC校验原理:怎么保证数据没错?
CRC,循环冗余校验。名字听着唬人,其实原理不复杂。就是把整个数据包当成一个巨大的二进制数,然后除以一个固定的多项式。余数就是CRC值。
MAVLink用的是CRC-16-CCITT,多项式是0x1021。我刚开始做的时候,自己手算过一遍,算到半夜才搞明白。后来直接用现成的查表法,效率高得多。
核心要点:MAVLink的CRC不是只算负载,而是把整个包(包括头部)都算进去。而且v2.0还额外加了一个密钥字节,防止恶意篡改。
代码实现其实很简单。我贴一段常用的CRC计算函数:
uint16_t crc_calculate(const uint8_t *data, uint16_t len) {
uint16_t crc = 0xFFFF;
for (uint16_t i = 0; i < len; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0x8408;
} else {
crc >>= 1;
}
}
}
return crc;
}
这段代码我用了好几年,从来没出过问题。你想想看,飞控每毫秒都在发数据,如果CRC算错了,那整个系统就乱套了。
小技巧:调试时可以用MAVLink Inspector工具。它能实时解析每个包的CRC是否正确。我曾经靠它抓到一个硬件问题——某款USB转串口模块在高速传输时会偶尔翻转一个bit,CRC直接报错。
1.4 知识体系总览
说了这么多,咱们用一张图把今天的内容串起来。我画了个流程图,把MAVLink协议的核心逻辑展示清楚:
避坑指南:我曾经遇到过一个坑——CRC计算时忘了包含密钥字节。结果地面站收包一切正常,但飞控就是不认。查了两天才发现,v2.0的CRC计算规则和v1.0不一样。所以,升级协议版本时一定要重新核对校验逻辑。
好了,今天的内容就到这里。MAVLink协议基础是后面所有章节的基石。你把这个搞透了,后面讲指令发送、消息解析、超时重传,都会轻松很多。
课后建议:打开你的地面站,抓一段真实的MAVLink日志。用Wireshark或者MAVLink Inspector看看每个字段的值。纸上得来终觉浅,亲手拆一个包比看十遍文档都管用。