包的序列化

本主题提供有关 MAVLink 数据包序列化、 (包括 MAVLink v1 和 v1 数据包的线格式)、 消息有效负载中字段的排序、和 CRC_EXTRA 用于确保发件人和收件人共享兼容的邮件定义。

主要是为正在创建/维护 MAVLink 生成器的开发者

MAVLink 用户通常不需要理解序列化格式,因为编码/解码由 MAVLink 库处理。

数据包格式

本节显示 MAVLink 数据包的序列化消息格式(格式由CAN 和 SAE AS-4 标准启发)。

MAVLink 2 的数据包格式

下面是 MAVLink 2 数据包的线外格式 (内存中的表示形式可能会有所不同)。

MAVLink v2 数据包

字节索引C 版本内容说明
0uint8_t magic数据包启动标记0xFD特定于协议的文本启动 (stx) 标记, 用于指示新数据包的开始。 任何不识别协议版本的系统都将跳过数据包。
1uint8_t len载荷长度0 - 255显示 有效载荷部分的长度。 这可能会受到 payload truncation 的影响。
2uint8_t incompat_flags不兼容标志必须理解为 MAVLink 兼容性的标志 (如果不理解标志, 则实现丢弃数据包)。
3uint8_t compat_flags兼容性标志如果不识别, 则可以忽略的标志 (即使不识别标志, 实现仍然可以处理数据包)。
4uint8_t seq数据包序列号0 - 255用于检测数据包丢失。 组件为发送的每封消息递增值。
5uint8_t sysid系统 ID (发送者)1 - 255发送消息的 system (飞机) 的 ID。 用于区分网络上的系统。 Note that the broadcast address 0 may not be used in this field as it is an invalid source address.
6uint8_t compid组件ID (发送者)1 - 255component 发送消息ID。 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至9uint32_t msgid:24消息 ID (低、中级、高字节)0 - 16777215有效载荷中的 message type 的 id。 用于将数据解码回消息对象。
10至 (n+10)uint8_t payload[max 255]负载消息数据。 取决于消息类型 (即消息 ID) 和内容。
(n+11) to (n+12)uint16_t checksumChecksum(低字节, 高字节)X.25 CRC 表示消息 (不包括 magic 字节)。 包括 CRC_EXTERA 字节。
(n+12) 至 (n+26)uint8_t signature[13]签名(可选) 签名以确保链接不受篡改。
  • 最低数据包长度是11字节,用于没有有效载荷确认数据包。
  • 最大数据包长度为 279 字节,用于使用整个有效载荷。

MAVLink 1 的数据包格式

下面是 MAVLink 1 数据包的线外格式 (内存中的表示形式可能会有所不同)。

MAVLink v1 数据包

字节索引C 版本内容说明
0uint8_t magic数据包启动标记0xFE特定于协议的文本启动 (stx) 标记, 用于指示新数据包的开始。 任何不识别协议版本的系统都将跳过数据包。
1uint8_t len载荷长度0 - 255指示以下 payload 部分的长度 (为特定消息固定)。
2uint8_t seq数据包序列号0 - 255用于检测数据包丢失。 组件为发送的每封消息递增值。
3uint8_t sysid系统 ID1 - 255发送消息的 system (飞机) 的 ID。 用于区分网络上的系统。 Note that the broadcast address 0 may not be used in this field as it is an invalid source address.
4uint8_t compid组件ID1 - 255component 发送消息ID。 用于区分 system 中的组件 (例如自动驾驶仪和相机)。 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.
5uint8_t msgid消息 ID0 - 255有效载荷中的 message type 的 id。 用于将数据解码回消息对象。
6至 (n+6)uint8_t payload[max 255]有效负载数据消息数据。 内容取决于消息类型(即消息ID)。
(n+7) 至 (n+8)uint16_t checksumChecksum(低字节, 高字节)X.25 CRC 表示消息 (不包括 magic 字节)。 包括 CRC_EXTERA 字节。
  • 最低数据包长度是8字节,用于没有有效载荷确认数据包。
  • 最大的数据包长度是完整有效载荷263字节。

不兼容标记 (MAVLink 2)

使用不兼容的旗帜来显示一个 MAVLink 库必须支持才能处理数据包。 这包括影响数据包格式/订制的任何功能。

如果 incompat_flags 字段中的任何标志不识别, 则 MAVLink 必须丢弃

支持的不兼容标志包括 (在编写本文时):

标记C 标志特性
0x01MAVLINK_IFLAG_SIGNED数据包 signed (签名已追加到数据包中)。

兼容性标记 (MAVLink 2)

兼容性标记用于显示功能,无法阻止 MAVLink 库处理数据包 (即使不能识别此功能)。 例如,这可能包括一个标志,以表明数据包应被视为“高度优先级”, (因为数据包格式和结构不受影响,这种信息可以通过任何 MAVLink 执行处理)。

一个 MAVLink 执行可以安全地忽略它在 compat_latime 字段中不识别的旗帜。

有效负载格式

MAVLink 没有包含关于有效载荷本身的信息结构的信息 (为了减少间接开销)! 相反, 发送方和接收方必须对无线格式的消息字段的含义、顺序和大小有共同的标识。

消息在 MAVLink 数据包中进行编码:

  • msgid(消息id) 字段确定了在数据包中编码的具体消息。
  • payload 字段包含消息数据。
  • len 字段包含有效负载数据的长度。
  • CRC_EXTRA 字节添加到消息 checksum。 接收器可以使用它来确认它与有效负载消息格式/定义兼容。

    如果消息规范不兼容 (例如 c 库 mavlink_parse_char() 给出状态 MAVLINK_FRAMING_BAD_CRC), 则 MAVLink 库应在解码过程中通知错误的 crc。

字段重新排序

消息有效载荷字段重新排序,以便传输如下:

  • Fields are sorted according to their native data size:
    • (u)int64_t, double (8 bytes)
    • (u)int32_t, float (4)
    • (u)int16_t (2)
    • (u)int8_t, char (1)
  • 如果两个字段的长度相同, 则它们的顺序将保留为数据字段大小排序之前的顺序
  • 根据它们使用的数据类型处理数组,而不是根据总数组大小处理
  • 已传输的报文与 construction 相同,因此代表重新排序的字段
  • CRC_EXTERA 字段在重新排序 计算,这可以确保字段中的错误可以被默认 CRC 发现。 提供的 Python, C 和 C# 参考执行测试,以便正确地重新排序,这只是习惯执行的关切。

上述重新排序的唯一例外是 MAVLink 2 扩展字段。 扩展字段以 XML-Declaration 的顺序发送,不包括在CRC_EXTERA 计算中。 这允许新的扩展字段在消息结束后附加,但不打破二进制兼容性。

此订单是独特的,可以通过使用稳定的分类算法,很容易在协议中轻松实现。 替代索引要么效率低下,不利于 MAVLink 应用的典型目标架构,或者要支持按变量大小为顺序的函数调用,而不是应用的上下文。 这将导致序列化函数的功能签名非常混乱。

空字节有效负载截断 (MAVLink 2)

MAVLink 2 在序列化有效载荷发送之前截断任何空的(零填充) 字节。 这与 MAVLink 1,在这种情况下,所有字段都发送了字节,因此,这是这样。

保存的实际字段/字节取决于消息及其内容 (MAVLink field reordering 意味着,我们可以说,任何截断字段通常都是最小的数据大小或扩展字段)。

The first byte of the payload is never truncated, even if the payload consists entirely of zeros.

The protocol only truncates empty bytes at the end of the serialized message payload; any null bytes/empty fields within the body of the payload are not affected.

CRC_EXTERA 计算

The CRC_EXTRA CRC is used to verify that the sender and receiver have a shared understanding of the over-the-wire format of a particular message.

Changes in message specifications that might make the over-the-wire format incompatible include: new/removed fields, or changes to field name, data type, order, or array length.

When the MAVLink code generator runs, it takes a checksum of the XML structure for each message and creates an array define MAVLINK_MESSAGE_CRCS. This is used to initialise the mavlink_message_crcs[] array in the C/C++ implementation, and is similarly used in the Python (or any other, such as the C# and JavaScript) implementation.

When the sender calculates the checksum for a message it adds the CRC_EXTRA byte onto the end of the data that the checksum is calculated over. The recipient calculates a checksum for the received message and adds its own CRC_EXTRA for the particular message id. If the CRC_EXTRA for the sender and receiver are different the checksums will not match.

This approach ensures that only messages where the sender and recipient are using the same message structure will be decoded (or at least it makes a mistake much more unlikely, as for any checksum application).

If you are doing your own implementation of MAVLink you can get this checksum in one of two ways: you can include the generated headers and use MAVLINK_MESSAGE_CRCS to get the right seed for each message type, or you can re-implement the code that calculates the seed.

As MAVLink internally reorders the message fields according to their size to prevent word / halfword alignment issues (see Data structure alignment (Wikipedia) for further reference), and a wrongly implemented reordering potentially can cause inconsistencies as well, the CRC_EXTRA is calculated based on the over-the-air message layout rather than the XML order.

MAVLink 2 extension fields are not included in the CRC_EXTRA calculation.

This is the Python code that calculates the CRC_EXTRA seed:

def message_checksum(msg):
    '''calculate a 8-bit checksum of the key fields of a message, so we
       can detect incompatible XML changes'''
    from .mavcrc import x25crc
    crc = x25crc()
    crc.accumulate_str(msg.name + ' ')
    # in order to allow for extensions the crc does not include
    # any field extensions
    crc_end = msg.base_fields()
    for i in range(crc_end):
        f = msg.ordered_fields[i]
        crc.accumulate_str(f.type + ' ')
        crc.accumulate_str(f.name + ' ')
        if f.array_length:
            crc.accumulate([f.array_length])
    return (crc.crc&0xFF) ^ (crc.crc>>8)

This uses the same x25 checksum that is used at runtime. It calculates a CRC over the message name (such as “RAW_IMU”) followed by the type and name of each field, space separated. The order of the fields is the order they are sent over the wire. For arrays, the array length is also added.

校验和

The packet format includes a 2-byte CRC to allow detection of message corruption. The checksum is the same as used in ITU X.25 and SAE AS-4 standards (CRC-16-CCITT), documented in SAE AS5669A. See the MAVLink source code for the documented C-implementation.

The CRC covers the whole message, excluding magic byte and the signature (if present). The CRC includes the CRC_EXTRA byte, which is used to ensure that the sending and receiving systems share a common understanding of the message definition.

results matching ""

    No results matching ""