PX4模块设计之四:MAVLink简介
- 1. MAVLink(PX4)应用简介
- 2. MAVLink v2.0新特性
- 3. MAVLink协议版本
- 4. MAVLink通信协议帧
- 4.1 MAVLink v1.0 帧格式
- 4.2 MAVLink v2.0 帧格式
- 5. MAVLink 签名报文
- 5.1 签名报文帧格式
- 5.1.1 Link IDs (链路ID)
- 5.1.2 Timestamp (时间戳)
- 5.1.3 Signature (签名)
- 5.2 签名报文有效性判断
- 5.3 非签名报文处理建议
- 5.4 错误签名报文处理建议
- 5.5 秘钥管理
- 6. 参考资料
基于PX4开源软件框架简明简介的框架设计,逐步分析内部模块功能设计。
前面了解了三种消息中间件中的一种uORB消息中间件,接下来看下MAVLink(Micro Air Vehicle Link,微型空中飞行器链路通讯协议)中间件。
1. MAVLink(PX4)应用简介
PX4使用MAVLink与QGroundControl(或者其他地面站软件),并且也用于飞控以外的伴飞电脑和摄像头通信与控制。
目前,MAVLink作为轻量级的通信协议,已被广泛应用与无人机系统。随着应用的拓展,基于该协议定义了一系列标准的消息和微服务用于飞控系统内的数据交互。
PX4开源代码将mavlink作为一个submodule集成到/src/modules/mavlink目录下,并在编译的时候自动生成MAVLink头文件(/build//mavlink/)。
默认使用的是/mavlink/messages/1.0/下的development配置文件development.xml。
注:该默认配置使用/src/modules/mavlink/CMakeLists.txt文件内的变量MAVLINK_DIALECT定义;
34 set(MAVLINK_DIALECT "development") # standard, development, etc
2. MAVLink v2.0新特性
- 24 bit message ID - 支持2^24=16,777,216个消息定义(MAVLink v1.0仅支持256个)
- Packet signing - 支持信任签名机制,保证系统的可靠性。
- Message extensions - 新增字段并兼容支持之前的版本。
- Empty-byte payload truncation - 在发送之前,必须删除序列化负载末尾的空(零填充)字节(所有字节都在MAVLink 1中发送,而不管内容如何)。
- Compatibility Flags/Incompatibility Flags - 报文尝试解释和直接丢弃标记功能
3. MAVLink协议版本
- MAVLink 2.0: 当前/推荐 主要版本,于2017年开始采用。
- MAVLink v1.0: 广泛应用于2013年,目前仍有大量存量设备采用上述协议。
为确保存量版本v1.0和主流版本v2.0的兼容性,v2.0新增版本协商流程来判断飞控支持的协议版本,v2.0协商逻辑和流程如下:
- If the system supports MAVLink 2 and the handshake it will respond with PROTOCOL_VERSION encoded as MAVLink 2 packet.
- If it does not support MAVLink 2 it should NACK the command.
- The GCS should fall back to a timeout in case the command interface is not implemented properly.
![](http://image109.360doc.cn/DownloadImg/2023/07/0320/268595230_6_20230703083756104.png)
4. MAVLink通信协议帧
4.1 MAVLink v1.0 帧格式
![MAVLink 1 Packet Format](https://img-blog.csdnimg.cn/8e7e63e5cff840b9b09c7c33e27b77da.png)
Byte Index | C version | Content | Value | Explanation |
---|---|---|---|---|
0 | uint8_t magic | Packet start marker | 0xFE | Protocol-specific start-of-text (STX) marker used to indicate the beginning of a new packet. Any system that does not understand protocol version will skip the packet. |
1 | uint8_t len | Payload length | 0 - 255 | Indicates length of the following payload section (fixed for a particular message). |
2 | uint8_t seq | Packet sequence number | 0 - 255 | Used to detect packet loss. Components increment value for each message sent. |
3 | uint8_t sysid | System ID | 1 - 255 | ID of system (vehicle) sending the message. Used to differentiate systems on network. Note that the broadcast address 0 may not be used in this field as it is an invalid source address. |
4 | uint8_t compid | Component ID | 1 - 255 | ID of component sending the message. Used to differentiate components in a system (e.g. autopilot and a camera). Use appropriate values in MAV_COMPONENT. Note that the broadcast address MAV_COMP_ID_ALL may not be used in this field as it is an invalid source address. |
5 | uint8_t msgid | Message ID | 0 - 255 | ID of message type in payload. Used to decode data back into message object. |
5+n | uint8_t payload[max 255] | Payload data | Message data. Content depends on message type (i.e. Message ID). | |
(6+n) to (7+n) | uint16_t checksum | Checksum (low byte, high byte) | CRC-16/MCRF4XX for message (excluding magic byte). Includes CRC_EXTRA byte. |
- 最小包8字节(acknowledgment packets without payload)
- 最长包263字节
4.2 MAVLink v2.0 帧格式
![](http://image109.360doc.cn/DownloadImg/2023/07/0320/268595230_7_20230703083756541.png)
Byte Index | C version | Content | Value | Explanation |
---|---|---|---|---|
0 | uint8_t magic | Packet start marker | 0xFD | Protocol-specific start-of-text (STX) marker used to indicate the beginning of a new packet. Any system that does not understand protocol version will skip the packet. |
1 | uint8_t len | Payload length | 0 - 255 | Indicates length of the following payload section. This may be affected by payload truncation. |
2 | uint8_t incompat_flags | Incompatibility Flags | Flags that must be understood for MAVLink compatibility (implementation discards packet if it does not understand flag). | |
3 | uint8_t compat_flags | Compatibility Flags | Flags that can be ignored if not understood (implementation can still handle packet even if it does not understand flag). | |
4 | uint8_t seq | Packet sequence number | 0 - 255 | Used to detect packet loss. Components increment value for each message sent. |
5 | uint8_t sysid | System ID (sender) | 1 - 255 | ID of system (vehicle) sending the message. Used to differentiate systems on network. Note that the broadcast address 0 may not be used in this field as it is an invalid source address. |
6 | uint8_t compid | Component ID (sender) | 1 - 255 | ID of component sending the message. Used to differentiate components in a system (e.g. autopilot and a camera). Use appropriate values in MAV_COMPONENT. Note that the broadcast address MAV_COMP_ID_ALL may not be used in this field as it is an invalid source address. |
7 to 9 | uint32_t msgid:24 | Message ID (low, middle, high bytes) | 0 - 16777215 | ID of message type in payload. Used to decode data back into message object. |
9+n | uint8_t payload[max 255] | Payload | Message data. Depends on message type (i.e. Message ID) and contents. | |
(10+n) to (11+n) | uint16_t checksum | Checksum (low byte, high byte) | CRC-16/MCRF4XX for message (excluding magic byte). Includes CRC_EXTRA byte. | |
(n+12) to (n+25) | uint8_t signature[13] | Signature | (Optional) Signature to ensure the link is tamper-proof. |
- 最小包12字节(acknowledgment packets without payload)
- 最长包280字节(a signed message that uses the whole payload)
5. MAVLink 签名报文
MAVLink 2.0 packet signing proposal
国内下载链接
5.1 签名报文帧格式
带签名的包incompatibility flag field的第一位0x01置位,最后的13 字节签名追加到报文最后面。
![](http://image109.360doc.cn/DownloadImg/2023/07/0320/268595230_8_2023070308375788.png)
Data | Description |
---|---|
linkID (8 bits) | ID of link on which packet is sent. Normally this is the same as the channel. |
timestamp (48 bits) | Timestamp in 10 microsecond units since 1st January 2015 GMT time. This must monotonically increase for every message on a particular link. Note that means the timestamp may get ahead of the actual time if the packet rate averages more than 100,000 packets per second. |
signature (48 bits) | A 48 bit signature for the packet, based on the complete packet, timestamp, and secret key. |
注:(SystemID,ComponentID,LinkID)组成一个stream流。
5.1.1 Link IDs (链路ID)
8位链路ID主要用于确保签名通信系统内多个链路之间的交叉干扰和冲突。
5.1.2 Timestamp (时间戳)
48位时间戳的单位是10us,计算时间从2015年1月1日(GMT)开始。每个stream流,后到报文必须比前面的报文时间晚, 以确保系统报文的前后顺序。
5.1.3 Signature (签名)
48位签名采用SHA-256 hash,计算方法如下:
signature = sha256_48(secret_key + header + payload + CRC + link-ID + timestamp)
注:32字节的秘钥保存在MAVLink链路的两端设备,用于验证信息的正确性。
5.2 签名报文有效性判断
报文有效除以下条件外:
- 同一链路内报文时间戳晚于之前报文。
- 同一链路内报文时间前后相差1分钟 (6,000,000us) 。
- 48位签名计算值与报文签名不符。
5.3 非签名报文处理建议
非签名报文接收建议(理论上来说只要报文完整,都可以被接收):
- 通过安全通道的非签名报文可以都接收(比如:有线连接USB,Ethernet )。
- 根据系统具体参数接收所有非签名报文。
- RADIO_STATUS报文始终接收。
- 在非签名报文模式,接收所有非签名报文(也许报文是硬件触发消息,比如:boot按钮)。
- 无条件接收所有非签名报文直到收到签名报文后,进入严格的签名报文有效性验证。
5.4 错误签名报文处理建议
可以选择性提供错误签名报文的处理,比如:丢失飞机的GPS坐标信息。
5.5 秘钥管理
密钥是32字节的二进制数据,用于创建可由密钥持有人验证的消息签名。密钥应该在网络中的一个系统(通常是地面站系统)上创建,并通过安全通道共享给其他受信任的设备。系统必须具有共享密钥才能进行通信。
密钥应存储在永久存储器中,不得通过任何可公开访问的通信协议公开。特别是,密钥不得暴露在MAVLink参数、MAVLink日志文件或可用于公共日志分析的dataflash日志文件中。
使用SETUP签名消息将密钥共享给其他设备。消息只能通过安全链路(如USB或有线以太网)作为直接消息发送到每个连接的system_id/component_id。必须设置接收系统来处理消息,并将接收到的密钥存储到适当的永久存储器中。
6. 参考资料
【1】MAVLink Messaging
【2】MAVLink官网介绍
【3】MAVLink Git代码