Сб янв 16, 2021 03:35:38
Когда отправитель вычисляет контрольную сумму для сообщения, он добавляет CRC_EXTRA_байт в конец данных, по которым вычисляется контрольная сумма. Получатель вычисляет контрольную сумму для полученного сообщения и добавляет свою собственную CRC_EXTRA для конкретного идентификатора сообщения.
Если CRC_EXTRA для отправителя и получателя разные, контрольные суммы не будут совпадать.
Такой подход гарантирует, что будут декодированы только сообщения, в которых отправитель и получатель используют одну и ту же структуру сообщения
(или, по крайней мере, это делает ошибку гораздо менее вероятной, как для любого приложения контрольной суммы).
Сб янв 16, 2021 21:00:44
Экстракция CRC защищает пакет от декодирования другой версии того же пакета, но с другими переменными.
Это средство гарантировать, что случайное смешение диалектов или версий MAVLink никогда не приведет к неверной интерпретации данных.
Они определены в каждом файле диалекта, например, в common.h или pixhawk.h.
Это пример из common.h:
#ifndef MAVLINK_MESSAGE_CRCS
#define MAVLINK_MESSAGE_CRCS {50, 124, 137, 0, 237, 217, 104, 119, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 214, 159, 220, 168, 24, 23, 170, 144, 67, 115, 39, 246, 185, 104, 237, 244, 222, 212, 9, 254, 230, 28, 28, 132, 221, 232, 11, 153, 41, 39, 214, 223, 141, 33, 15, 3, 100, 24, 239, 238, 30, 200, 183, 0, 130, 0, 148, 21, 0, 52, 124, 0, 0, 0, 20, 0, 152, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 183, 63, 54, 0, 0, 0, 0, 0, 0, 0, 175, 102, 158, 208, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 49, 170, 44, 83, 46, 0}
#endif
Это кодировка сообщения:
контрольная сумма = crc_calculate ((uint8_t *) & msg-> len, length + MAVLINK_CORE_HEADER_LEN);
#if MAVLINK_CRC_EXTRA
crc_accumulate (crc_extra, & контрольная сумма);
#endif
mavlink_ck_a (msg) = (uint8_t) (контрольная сумма & 0xFF);
mavlink_ck_b (msg) = (uint8_t) (контрольная сумма >> ;
Вы видите, что к контрольной сумме добавляется полная полезная нагрузка плюс заголовок, так как все, начиная с поля "len", берется в контрольную сумму:
typedef struct __mavlink_message {
uint16_t контрольная сумма; /// отправлено в конце пакета
uint8_t magic; /// <магический маркер протокола
uint8_t len; /// <Длина полезной нагрузки
uint8_t seq; /// <Последовательность пакета
uint8_t sysid; /// <ID системы отправителя сообщения / самолета
uint8_t compid; /// <ID компонента отправителя сообщения
uint8_t msgid; /// <ID сообщения в полезной нагрузке
uint64_t payload64 [(MAVLINK_MAX_PAYLOAD_LEN + MAVLINK_NUM_CHECKSUM_BYTES + 7) / 8];
} mavlink_message_t;
Таким образом, вы должны вычислить контрольную сумму по полному заголовку, всем байтам полезной нагрузки и, наконец, добавить байт CRC_EXTRA.
Это должно дать вам тот же результат.
Вс янв 17, 2021 02:00:01
Вс янв 17, 2021 05:55:59
Ср янв 27, 2021 05:27:06
Ср янв 27, 2021 06:41:08
Ср янв 27, 2021 13:17:41
;******************************************************************************
; Загрузка 16-битового регистра CRC числом FFFF.
CRC_Modbus:
movlw 0xFF ; W <- 0xFF (DEC 255)
movwf CRC16_H ; CRC16_H <- W
movwf CRC16_L ; CRC16_L <- W
;******************************************************************************
; XOR байта с содержимым CRC. Результат в CRC.
VXOD:
movf Byte_X, W ; W <- Byte_X
xorwf CRC16_L, F ; CRC16_L <- W(Byte_X) xor CRC16_L
;******************************************************************************
; Предустановка счетчика циклов для прокрутки 1 байта
movlw 0x08 ; W <- 0x08 (DEC 8)
movwf Cycle_I ; Cycle_I <- W(0x08)
;******************************************************************************
; Сдвиг регистра CRC вправо (к младшему биту) на 1 бит,
; старший заполнить нулями.
CRC_SDVIG:
bcf STATUS, C ; очистка флага С в "0"
rrf CRC16_H, F ; CRC16_H <- (C>> CRC16_H >> 1 бит >>C)
rrf CRC16_L, F ; CRC16_L <- (C>> CRC16_L >> 1 бит >>C)
;******************************************************************************
; Проверка условия: если младший бит был "0", то перейти к "CRC_SDVIG"
; если младший бит был "1", то CRC xor A001.
btfss STATUS, C ; если мл. бит БЫЛ = "0", то PC+1, иначе PС+2
goto CRC_PER5 ; PC+1: переход на метку CRC_PER5
movlw 0xA0 ; PC+2: W = 0xA0 (DEC 160)
xorwf CRC16_H, F ; CRC16_H <- W(0xA0) xor CRC16_H
movlw 0x01 ; W = 0x01 (DEC 1)
xorwf CRC16_L, F ; CRC16_L <- W(0x01) xor CRC16_L
;******************************************************************************
; 5.Шаги №3 и №4 повторяются 8 раз.
CRC_PER5:
decfsz Cycle_I,F ; Cycle_I <- Cycle_I - 1. Если "0", то PC+2
goto CRC_SDVIG ; PC+1: переход на метку CRC_SDVIG
; PC+2: дальшейшее выполнение программы
;******************************************************************************
; 6.Шаги №2, №3, №4, №5 повторить для всех байт сообщения.
goto VXOD ; Переход на метку VXOD
Чт янв 28, 2021 02:44:30
Пн фев 01, 2021 00:00:07