Это перевод документации с описанием протокола CRSF [1]. Этот протокол применяется для передачи данных управления квадрокоптерами по радиоканалу. Непонятные термины и сокращения см. в разделе Словарик.
Функциональные возможности протокола CRSF:
• Высокая скорость передачи данных с низкими задержками между RC - TX и RX - FC. • Двунаправленный обмен данными. • Передача телеметрии летающей платформы на пульт управления (RC). • Редактирование конфигурации для устройств, подключенных напрямую или удаленно (RC может конфигурировать FC или OSD по протоколу CRSF). • Передача серийного номера приемника в TX, чтобы его можно было сопоставить с памятью модели.
Этот документ служит публичным "единым источником истины", поддерживаемым TBS [2], документируя протокол. Он служит справочным материалом для реализации CRSF-совместимых устройств, а также позволяет разработчикам, не связанным с TBS, озвучивать требования и предлагать расширения к существующим протоколам. Он также установит CRSF как наиболее широко внедренный современный протокол связи для устройств R/C.
[Аппаратура CRSF]
Single-Wire Half-Duplex UART. Эта обычно используемая конфигурация сигнала между RC и TX. RC в этом случае действует как master, и TX отвечает телеметрией, если он синхронизирован с кадрами RC, посылаемыми RC. RC должен посылать только один кадр с предварительно сконфигурированной или согласованной частотой, и должен переключить линию в состояние высокого сопротивления, и ждать ответа от TX.
UART по умолчанию работает на на скорости 400 kbaud (baudrate) с форматом 8N1 (с инверсией или без) на уровнях TTL-логики 3.3V, однако также поддерживается 115.2 kbaud и более высокие скорости (1Mbaud, 2Mbaud), в зависимости от аппаратуры (см. 0x70 CRSF Protocol Speed Proposal). Рекомендуется, чтобы модули TX были сконфигурированы на на одинаковую скорость, или автоматически определять скорость передачи. Максимальная частота кадров (frame-rate) должна быть выбрана в зависимости от baudrate для возможности передачи кадров RC и TX максимальной длины (64 байта в одном кадре).
Dual-Wire Full-Duplex UART. Эта конфигурация обычно используется на стороне летающей платформы. Два устройства соединяются друг с другом обычным линком UART (сигналы RXD и TXD, передающими данные дуплексом в обоих направлениях). В этой конфигурации поддерживается только не инвертированный (обычный) UART. UART по умолчанию работает на скорости 416666 baud, кадр 8N1 с уровнями между 3.0V и 3.3V, однако скорость может быть согласована на более высокую, чтобы реализовать ускоренную передачу данных и снизить задержки.
Multi-master I2C (BST). (EOL) BST это шина I2C с несколькими главными устройствами (multi master I2C). Она работает с уровнями 3.3V на скорости 100kHz, используя 7-бит адресацию. Адреса устройства уже содержат бит R/W. Это означает, что адрес записи меньше адреса чтения на 1. Каждое устройство, поддерживающее BST, должно освободить SDA в любом случае, чтобы не блокировать шину. Рекомендуется мониторить heartbeat-сообщение и сбрасывать интерфейс, если произошел таймаут 1.5 сек. Необходимо поддерживать кадры общего вызова, которые в этом документе называются broadcast кадрами.
[Структура кадра CRSF]
Базовая структура каждого кадра одна и та же. Существует ряд типов кадров с расширенным заголовком, в котором будут стандартизированы первые несколько байт полезной нагрузки. Это требуется для маршрутизации кадров между несколькими устройствами, чтобы реализовать обмен данными точка-точка. Каждый кадр CRSF имеет длину не более 64 байта (включая байты Sync и CRC).
Broadcast Frame
Sync byte
Frame Length
Type
Payload
CRC
[Sync byte] [Frame Length] [Type] [Payload] [CRC]
Extended Header Frame
Sync byte
Frame Length
Type
Destination Address
Origin Address
Payload
CRC
Из чего состоит кадр:
• Sync byte может быть одним из следующих (т. е. принимающее устройство должно ожидать любой из них):
- Serial sync byte: 0xC8; - Broadcast device address: 0x00; - Device address (адреса см. далее).
• Frame length: количество байт в кадре, исключая байт Sync и Frame Length (в основном это полный размер кадра -2)
- Broadcast Frame: Type + Payload + CRC - Extended header frame: Type + Destination address + Origin address + Payload + CRC - Допустимый диапазон между 2 и 62. Если это значение uint8 выходит из допустимого диапазона, то кадр должен быть отброшен.
• Type: тип кадра
• Payload: полезная нагрузка (данные)
Порядок байт многобайтных значений (endianness): Big endian (MSB) [6].
Размер кадра может превышать ожидаемый размер кадра для определенного типа. Это не должно быть причиной считать кадр некорректным. Приемник кадра должен просто игнорировать лишние поля. Возможно, что отправитель кадра поддерживает более новую версию протокола CRSF и отправляет некоторые дополнительные поля после известных полей.
И наоборот: если в кадре имеются некоторые опциональные (не обязательные) поля, то иногда эти поля могут быть установлены как пустые (например, строка ASCIIZ нулевой длины), но иногда эти поля могут отсутствовать, и размер кадра может быть сокращен. Не пытайтесь читать поля за пределами полезной нагрузки кадра.
Маршрутизация. Если в устройстве больше одного порта CRSF, то необходимо переслать все принятые кадры на другие порты. CRSF работает как звездообразная сеть с фиксированными адресными таблицами на каждом узле сети. Запрещается использовать любое циклическое соединение, так как оно будет бесконечно пересылать одно и то же сообщение.
CRC. Контрольная сумма кадра вычисляется от Type и Payload (данные байт sync и frame length не включаются). Используется алгоритм CRC8 с полиномом x7+ x6+ x4+ x2+ x0 (0xD5)
uint8_t fix_type; // Текущее качество фиксации GPSint16_t n_speed; // Скорость в сторону севера, north [см/сек] (в сторону севера// n_speed положительное, в сторону юга отрицательное)int16_t e_speed; // Скорость в сторону востока, east [см/сек] (в сторону востока// e_speed положительное, в сторону запада отрицательное)int16_t v_speed; // Вертикальная скорость [см/сек] (вверх v_speed положительное)int16_t h_speed_acc; // Точность горизонтальной скорости, см/секint16_t track_acc; // Точность курса, градусы в масштабе 1e-1 умножить на 10int16_t alt_ellipsoid; // Высота в метрах над эллипсоидом GPS (не MSL)int16_t h_acc; // Горизонтальная точность в смint16_t v_acc; // Вертикальная точность в смuint8_t reserved;
uint8_t hDOP; // Горизонтальное снижение точности, безразмерные единицы .1.uint8_t vDOP; // Вертикальное снижение точности, безразмерные единицы .1.
0x07 Variometer Sensor
int16_t v_speed; // Вертикальная скорость, см/сек
0x09 Barometric Altitude & Vertical Speed
Этот кадр позволяет отправить высоту и вертикальную скорость более эффективным в плане количества бит способом. Он позволяет комбинировать в 3 байтах высоту дециметровой точности с 32 км диапазоном и 3 см/сек точностью вертикальной скорости в диапазоне 25 м/сек.
uint16_t altitude_packed; // Высота выше стартовой (калиброванной) точки// См. описание далее.int8_t vertical_speed_packed; // Вертикальная скорость. См. описание далее.
Значение высоты зависит от MSB (бит 15):
MSB = 0: высота в дециметрах - 10000 dm смещение (так что 0 представляет -1000 м; 10000 представляет 0 м (стартовая высота); 0x7fff представляет 2276.7 м); MSB = 1: высота в метрах, без какого-либо смещения.
// Поскольку OpenTX считает любое значение 0xFFFF как некорректное, то // максимальное посылаемое значение ограничено 0xFFFE (32766 метров). // Пример функции упаковки: uint16_tget_altitude_packed(int32_t altitude_dm)
{
enum
{
ALT_MIN_DM = 10000, // min высота в dm (дециметры)
ALT_THRESHOLD_DM = 0x8000 - ALT_MIN_DM, // точность изменения высоты в dm
ALT_MAX_DM = 0x7ffe * 10 - 5, // max высота в dm
} if(altitude_dm < -ALT_MIN_DM) // меньше минимальной амплитудыreturn0; // минимумif(altitude_dm > ALT_MAX_DM) // больше максимальной амплитудыreturn0xfffe; // максимумif(altitude_dm < ALT_THRESHOLD_DM) // диапазон dm-разрешающей способностиreturn altitude_dm + ALT_MIN_DM;
return ((altitude_dm + 5) / 10) | 0x8000; // диапазон m-разрешающей способности
}
Вертикальная скорость, представленная в см/сек, с логарифмической шкалой. Функции её распаковки и упаковки:
16 каналов управления, упакованные в 22 байта. В случае Failsafe этот кадр больше не будет посылаться (когда тип failsafe установлен в "cut"). Рекомендуется подождать 1 секунду перед запуском подпрограммы FC failsafe.
struct
{int channel_01: 11;
int channel_02: 11;
int channel_03: 11;
int channel_04: 11;
int channel_05: 11;
int channel_06: 11;
int channel_07: 11;
int channel_08: 11;
int channel_09: 11;
int channel_10: 11;
int channel_11: 11;
int channel_12: 11;
int channel_13: 11;
int channel_14: 11;
int channel_15: 11;
int channel_16: 11;
};
0x17 Subset RC Channels Packed
Предупреждение: этот кадр не рекомендуется для реализации. Выполняется ревизия.
// Пример вычисления значений rc в значения канала: #define PACK_TX(x) ((x - 3750) * 8 / 25 + 993) #define UNPACK_RX(x, S) (x * S + 988) // S = 1.0 для 10 бит, S = 0.5 для 11 бит, S = 0.25 для 12 бит, S = 0.125 для 13 бит
structPACKED
{uint8_t starting_channel:5; // какой номер канала первый в кадреuint8_t res_configuration:2; // конфигурация для разрешающей// способности данных RC (10 - 13 бит)uint8_t digital_switch_flag:1; // бит конфигурации для цифрового каналаuint16_t channel[]:resolution; // переменное количество каналов// (с переменной разрешающей способностью// в зависимости от res_configuration)// на основе размера кадраuint16_t digital_switch_channel[]:10; // канал цифрового коммутатора
};
0x18 RC Channels Packed 11-bits (не используется)
То же самое что и 0x16, но с таким же стилем преобразования, как у 0x17.
0x19 - 0x1B Reserved Crossfire
0x1C Link Statistics RX
uint8_t rssi_db; // RSSI (dBm * -1)uint8_t rssi_percent; // RSSI в процентахuint8_t link_quality; // Package success rate / Link quality (%)int8_t snr; // SNR (dB)uint8_t rf_power_db; // мощность радиоканала в dBm
0x1D Link Statistics TX
uint8_t rssi_db; // RSSI (dBm * -1)uint8_t rssi_percent; // RSSI в процентахuint8_t link_quality; // Package success rate / Link quality (%)int8_t snr; // SNR (dB)uint8_t rf_power_db; // мощность радиоканала в dBmuint8_t fps; // количество кадров в секунду (fps / 10)
0x1E Attitude
Предупреждение: значения угла должны быть в диапазоне -180° +180°!
int16_t airspeed;
uint8_t base_mode; // флаги режима устройства, определенные// в MAV_MODE_FLAG enumuint32_t custom_mode; // флаги, относящиеся к автопилотуuint8_t autopilot_type; // тип FC; определен в MAV_AUTOPILOT enumuint8_t firmware_type; // тип устройства; определен в MAV_TYPE enum
uint8_t VAL1; // Используется для положения сиденья пилотаuint8_t VAL2; // Используется для текущего круга пилотовchar VAL3[15]; // 15 символов для текущего/разделенного времени кругаchar VAL4[15]; // 15 символов для текущего/разделенного времени кругаchar FREE_TEXT[20]; // Произвольный текст из 20 символов в нижней части// экрана
0x27 Reserved
[Extended Frame Types]
Кадры типа 0x28 и выше (если явно не указано нечто иное) имеют расширенный заголовок (extended header), с полями точки назначения (destination) и источника (origin).
0x28 Parameter Ping Devices
Хост может посылать ping на указанное устройство (адрес узла назначения устройства) или на все устройства (адрес узла назначения 0x00 Broadcast address), и они ответят кадром информации об устройстве (Parameter device information). У кадра нет полезной нагрузки.
0x29 Parameter Device Information
char[] Device_name; // ASCIIZ-строкаuint32_t Serial_number;
uint32_t Hardware_ID;
uint32_t Firmware_ID;
uint8_t Parameters_total; // общее количество параметровuint8_t Parameter_version_number;
Блоки пакета. Максимальный размер кадр CRSF равен 64 байта (включая байт sync и CRC). Хост всегда должен читать (0x2C Parameter settings (read)) блок номер 0 по умолчанию. Если параметр чтения (0x2B Parameter settings (entry)) укладывается в максимальный размер, то он ответит блоками оставшимися 0 внутри кадра параметра. Иначе он будет посылать столько блоков, сколько осталось фрагментов для чтения.
Пример цепочки кадров Parameter settings (0x2B и 0x2C):
Блок полезной нагрузки кадров имеет следующую структуру:
uint8_t Parameter_number; // начинается от 0 uint8_t Parameter_chunks_remaining; // количество оставшихся блоков
Part of Parameter settings(entry) payload. // до 56 байт
0x2B Parameter Settings (Entry)
Так устройство (адрес узла) может совместно использовать параметр с другим устройством. См. выше "Блоки пакета".
Замечание: если Data_type_payload_chunk ≤ 56, то может быть отправлен 1 кадр, иначе полезная нагрузка будет передаваться блоками в 2 или большего количества кадров.
uint8_t Sync_byte; // 0xc8uint8_t Frame_length;
uint8_t Frame_type; // 0x2b = Parameter settings (entry)uint8_t Destination_address; // 0xea = RCuint8_t Origin_address; // 0xee = TXuint8_t Parameter_number; // начинается от 0uint8_t Parameter_chunks_remaining; // количество оставшихся блоков
{
Data_type_payload_chunk; // см. ниже полезную нагрузку для каждого типа
}
uint8_t CRC_8; // Frame CRC (см. описание CRC)
Определение типа параметров и бит скрытости. Тип параметра имеет разрядность 8 бит. Бит 7 показывает скрытость параметра (1 = скрытый / 0 = видимый). Это дает возможность динамически показывать и скрывать параметры в зависимости от других параметров. Биты 6 .. 0 хранят информацию о типе параметра (перечисление data_type).
OUT_OF_RANGE. Этот тип будет отправлен, если будет запрошен номер параметра из диапазона параметров устройства. Он также будет отправлен в качестве последнего параметра, чтобы хост знал конец списка параметров в списке Parameters settings (запрос чтения).
UINT8, INT8, UINT16, INT16, UINT32, INT32. Предлагается к исключению. А настоящее время эти типы реализованы через тип FLOAT, который более общий.
FLOAT. Value, min, max и default отправляются как INT32. Значение Decimal_point указывает, сколько цифр значения находится за десятичной точкой. Step_size это рекомендуемый инкремент или декремент для изменения Value.
TEXT_SELECTION. Часть значения этой записи разделена на две части. Первая это массив символов со всеми возможными значениями в текстовом формате. Они разделены символом точки с запятой (;), и массив завершается null-символом. Вторая часть это переменная uint8_t с текущим значением. Значения min, max и default представлены как числа uint8_t, где 0 представляет первый текст. Для изменения этого параметра только uint8_t value должно быть отправлено для нового значения.
Полезная нагрузка Text Selection:
uint8_t Parent folder; // номер параметра родительской папки,// 0 означает корневую (root) папкуenumdata_typeDatatype;// 0x09 = выбор текстаchar[] Name; // ASCIIZ строкаchar[] Options; // ASCIIZ строка, представляющая собой// список, где параметры отделяются// символом точки с запятойuint8_t Value;
uint8_t Min;
uint8_t Max;
uint8_t Default;
char[] Unit; // ASCIIZ строка
STRING. Этот тип предназначен для модификации текста. Будет передаваться только текущий текст. Для этого типа не посылаются min, max и default записи.
Полезная нагрузка String:
uint8_t Parent_folder; // номер параметра родительской папки,// 0 означает корневую (root) папкуenumdata_typeData_type;// 0x0a = stringchar[] Name; // ASCIIZ строкаchar[] Value; // ASCIIZ строкаuint8_t String_max_length; // только для типа string
FOLDER. Папка используется для улучшения структуры параметров. Каждый параметр имеет родительскую запись, где параметр может ссылаться на folder родителя. Дополнительно folder предоставит список его потомков и добавит имя folder. Конец списка маркируется байтом 0xFF. Список будет содержаться номер параметра потомка.
Полезная нагрузка Folder:
uint8_t Parent_folder; // номер параметра родительской папки,// 0 означает корневую (root) папкуenumdata_typeData_type;// 0x0b = folderchar[] Name; // ASCIIZ строкаuint8_t[] List_of_children; // записью 0xFF помечается конец списка
INFO. Значение в виде ASCIIZ-строки. То же самое, что и STRING, за исключением того, что запись INFO не может быть изменена и не включает максимальную длину.
COMMAND. С типом команды хост может запустить/выполнить на устройстве функцию. Это может быть что угодно: привязка канала (link bind crossfire), калибровка гироскопа/акселерометра, и т. п.
Статус по умолчанию устройства READY. Как только хост захотел выполнить функцию, он записывает параметр со статусом START. В зависимости от функции на устройстве оно переключается в статус PROGRESS, CONFIRMATION_NEEDED или READY.
Когда устройство посылает хосту статус CONFIRMATION_NEEDED, отобразится бокс с выбором подтверждения ("confirm") или отмены ("cancel"). Если пользователь выберет что-то из этого, то оно будет передано на устройство, и функция проложит выполняться. В полем Info устройство может послать дополнительную информацию на хост.
Если хост посылает статус POLL, то он этим заставит устройство послать обновленный статус 0x2B Parameter settings (entry).
Запрос определенного параметра. Эта команда предназначена для повторного запроса параметра/блока, который не прошел через линк.
uint8_t Parameter_number;
uint8_t Parameter_chunk_number; // номер блока для запроса,// начинающийся с 0
0x2D Parameter Value (Write)
Эта команда для переназначения параметра. Узел назначения (destination node) для проверки ответит кадром значения параметра (Parameter value frame), отправленным по адресу узла источника (origin node).
uint8_t Parameter_number;
Data; // размер зависит от типа данных
Замечание: размер зависит от типа данных, иначе эта запись не посылается, например:
• Для TEXT_SELECTION - размер 1; • Для FLOAT - размер 4.
0x32 Direct Commands
Кадр Command:
uint8_t Command_ID;
uint8_t[] Payload; // зависит от Command IDuint8_t Command_CRC8; // 8-битный CRC POLYNOM = 0xBA
Кадр команды защищен дополнительно вычисленной CRC в конце её полезной нагрузки. CRC включает тип кадра (байт 0x32), Destination, Origin, Command ID и Payload каждого Command Frame.
Замечание: полином отличается от основной CRC кадра CRSF. Command CRC не исключает CRC в конце каждого кадра CRSF. Вам также понадобится включить CRC в конец для полного кадра.
uint8_t Command_ID;
uint8_t SubCommand_ID;
uint8_t Action;
// 1 означает, что target уже предпринимает действие// 0 означает некорректную команду 0 или отсутствие// функции в этой командеuint8_t[] или char[] Information; // ASCIIZ-строка
- 0x01 DISCONTINUED VTX Change Channel - EVO, PRO32 HV, PRO32 NANO все еще это поддерживают. - 0x02 установка частоты - uint16_t Frequency (5000 - 6000 MHz) - 0x03 DISCONTINUED VTX Change Power (перемещено на 0x08) - 0x04 Enable PitMode при включении - uint8_t PitMode:1 enum (0 = OFF, 1 = ON) - uint8_t pitmode_control:2; (0=Off, 1=On, 2=Arm, 3=Failsafe) - uint8_t pitmode_switch:4; (0=Ch5, 1=Ch5 Inv, ... , 15=Ch12 Inv) - 0x05 Power up из PitMode (голая команда) - 0x06 Set Dynamic Power (15/05/2020 in EVO, PRO32 HV, PRO32 NANO) ЗАМЕЧАНИЕ: должно отправляться на 1Hz. Если не принято в течение 3 сек, то VTX возвратится к настройке питания "0x08 Set Power" - uint8_t Power (dBm) (0dBm может считаться как PitMode Power) - 0x08 Set Power - uint8_t Power (dBm) (0dBm может считаться как PitMode Power)
0x32.0x09 LED
- 0x01 Установка в умолчание (откат к специфическим для target настройкам) - 0x02 Переназначит LED color (packed) - 9 bits H (0-359°) - 7 bits S (0-100%) - 8 bits V (0-100%) - 0x03 Override pulse (packed) - uint16 duration (миллисекунды от начального color до конечного color) - 9 bits H_Start (0-359°) - 7 bits S_Start (0-100%) - 8 bits V_Start (0-100%) - 9 bits H_Stop (0-359°) - 7 bits S_Stop (0-100%) - 8 bits V_Stop (0-100%) - 0x04 Override blink (packed) - uint16 Interval - 9 bits H_Start (0-359°) - 7 bits S_Start (0-100%) - 8 bits V_Start (0-100%) - 9 bits H_Stop (0-359°) - 7 bits S_Stop (0-100%) - 8 bits V_Stop (0-100%) - 0x05 Override shift (packed) - uint16 Interval - 9 bits H (0-359°) - 7 bits S (0-100%) - 8 bits V (0-100%)
- 0x01 Установка приемника в режим привязки (bind mode) - 0x02 Отмена режима привязки - 0x03 Установка bind ID - 0x05 Выбор модели (команда для выбора модели/приемника) - uint8_t Model Number - 0x06 Текущий выбор модели (кадр запроса для текущего выбора) - 0x07 Ответ выбора текущей модели (кадр ответа текущего выбора) - uint8_t Model Number - 0x08 зарезервировано - 0x09 зарезервировано
0x32.0x12 Зарезервировано
0x32.0x20 Flow Control Frame
Устройство может ограничить скорость данных или подписаться на определенный кадр.
- 0x01 Subscribe (подписка) - uint8_t Frame type - uint16_t Max interval time // ms - 0x02 Unsubscribe (отписка) - uint8_t Frame type
0x32.0x22 Screen Command
Для всех устройств, у которых есть LCD Screen.
0x32.0x22.0x01 Pop-up Message Start
char[] Header; // ASCIIZ-строкаchar[] Info message; // ASCIIZ-строкаuint8_t Max_timeout_interval; // Время в секундахbool Close_button_option;
struct // не обязательное поле. Если его первый
// байт null (selectionText пуст),
// то это длиной только 1 байт (null).
{char[] selectionText; // ASCIIZ-строка. Если пусто,// то другие поля не существуют.uint8_t value;
uint8_t minValue;
uint8_t maxValue;
uint8_t defaultValue;
char[] unit; // ASCIIZ-строка единицы измерения
} add_data; // дополнительные данные для отображения// (например процент).char[] possible_values; // необязательное поле. Это массив// символов любых возможных ответов// значений в текстовом формате, разделенные// символом точки с запятой (;), и массив// заканчивается null.
Замечание: необязательные поля могут либо начинаться на null, либо даже не умещаться в кадр. Проанализируйте размер кадра и не считывайте необязательные поля за пределами полезной нагрузки кадра.
Наподобие "RC-sync"; наподобие "timing correction frame" (в EdgeTX).
uint32_t update_interval; // LSB = 100ns
int32 offset; // LSB = 100ns, положительные значения// означают, что данные пришли слишком// рано, отрицательные - слишком поздно.
Несмотря на то, что значения имеют разрешающую способность 100 нс, по крайней мере в EdgeTX это округляется до 1 мкс разрешающей способности 16-битных значений по прибытии.
• Кадр CRSF, который обертывает запрос MSP ( $M< или $X< ) • Поддерживается устройствами Betaflight • Поддерживаемые устройства будут отвечать 0x7B
0x7B
• Кадр CRSF, который обертывает ответ MSP ( $M>, $X>, $M!, $X! ) • Поддерживается устройствами Betaflight • Поддерживаемое устройство отравит этот кадр в ответ на MSP_Request (0x7A)
Кадр MSP, упакованный в полезную нагрузку CRSF Payload packing:
• У кадра MSP вырезается заголовок ($ + M/X + [/]/!) и CRC • Результирующее MSP-body может быть поделено на блоки, если оно не умещается в один кадр CRSF. • Байт 'Status' помещается перед MSP-body в каждом кадре CRSF. • Байт Status состоит итз трех частей:
- биты 0-3 представляют циклический номер кадра CRSF; - бит 4 проверяет, является ли текущий блок MSP началом (или только началом) нового кадра (1, если true); - биты 5-6 представляют номер версии протокола MSP (в настоящее время 1 или 2); - бит 7 представляет ошибку (только для ответа).
• Размер блока MSP-body вычисляется от размера кадра CRSF. Но размер MSP-body должен быть проанализирован из самого MSP-body (в отношении версии MSP и Jumbo-frame). • Последний/единственный кадр CRSF может быть длиннее необходимого. В таком случае лишние байты должны игнорироваться. • Максимальный размер блока определяется максимальной длиной кадра CRSF 64 байта, таким образом максимальный размер MSP-блока равен 57 байтам. Минимальная длина блока может быть любой, однако первый блок должен состоять из размера и идентификатора функции (то есть 5 байт для MSPv2). • CRC кадра MSP не посылается, потому что он уже защищен CRC кадра CRSF. Если требуется MSP CRC, то она должна вычисляться в точке приема. • MSP-ответ должен посылаться источнику MSP-запроса. Это значит, что байты [destination] и [origin] CRSF-заголовка в ответе должны быть такие же, как в запросе, но переставлены местами.
Кадры широковещания 0x80 и 0x81 устанавливают коммуникацию модулей mLRS TX со скриптами mLRS Configuration Lua, запущенными на например EdgeTx и OpenTx RC. Они инкапсулируют сообщения протокола mLRS 'mBridge' в кадрах CRSF. Протокол позволяет устанавливать параметры и другой функционал, но особенно также передает метаданные, которые необходимы для параметров модели mLRS, предоставляя для пользователя различную информацию, управления версией, и фичи, специфичные для системы линка mLRS.
0x80: Коммуникация из Lua script/RC до модуля TX. Формат кадра:\
0xEE
Frame Length
0x80
0x4F
0x57
Command byte
Payload
CRC
Два байта 0x4F, 0x57 это синхробайты протокола mBridge.
0x81: Коммуникация из модуля TX до Lua script/RC. Формат кадра:
0xEA
Frame Length
0x81
Command byte
Payload
CRC
Frame Length и CRC соответствуют спецификации CRSF, показанной выше. Протокол mBridge довольно сложен, поскольку служит mLRS для различных дополнительных целей помимо связи со сценарием конфигурации Lua.
Домашняя страничка проекта mLRS опубликована на GitHub [4]. См. также [5].
0xAA CRSF MAVLink Envelope
• Конверт CRSF MAVLink разработан для передачи протокола MAVLink через роутеры CRSF. Он поддерживает кадры MAVLink2 и MAVLink1. Поскольку кадры MAVLink обычно намного длиннее, чем кадры CRSF (281 байт для MAVLink2 против 64 байт для CRSF), MAVLink кадры будут разбиты на блоки.
• Обратите внимание, что кодирование / декодирование правильного количества блоков при записи / чтении конвертов MAVLink должно обрабатываться пользователем для обеспечения целостности данных.
uint8_t total_chunks : 4; // общее количество блоковuint8_t current_chunk : 4; // номер текущего блокаuint8_t data_size; // размер данных (максимум 58)uint8_t data[]; // массив данных (максимум 58 байт)
Получается структура кадра CRSF:
Sync byte (0xC8)
Frame Length
Type (0xAA)
totalChunk(bit3 - 7) : currChunk(bit0-3)
dataSize
dataStart ... dataEnd
CRC
0xAC CRSF MAVLink System Status Sensor
• Кадр CRSF для упаковки информации об упаковке статуса датчика MAVLink FC. • Для декодирования данных, упакованных в кадре, см. официальную wiki-документацию.
CRSF двоичный протокол на основе кадров для радиоуправляемых устройств.
EOL End of Life, продуктовая линейка, которая больше не выпускается.
FC Flight Controller, контроллер управления моделью (например квадрокоптер).
FPV First Person View, вид от первого лица. Подразумевается управление моделями, где установлена видеокамера, передающая изображение окружающей обстановки оператору.
MSP Message Send Protocol, протокол прикладного уровня, используемый для отправки коротких сообщений между узлами в сети. Первоначальная версия протокола была опубликована в 1990 году (из Википедии).
RC, R/C Remote Control: подразумевается пульт управления моделью (обычно по радиоканалу).
RSSI Received Signal Strength Indicator, показатель уровня принимаемого сигнала.
RX Receiver, приемник (который также является обычно трансивером). Может быть в виде отдельного устройства, или встроенным в FC или VTX.