ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
19 марта
976411
Evgeny_CD, Архитектор (04.02.2020 23:39 - 06.02.2020 19:23, просмотров: 42840)
[Универсальный код для передачи по байтовым и более широким каналам связи. Часть 1] Итог многих лет моих размышлений. Пусть мы хотим предавать пакеты, содержащие поля, в том числе неизвестной на момент передачи длины, по байтовому каналу (или шире, можно и по 7 битному, оверхед будет чуть больше), передавать многопоточно в пределах одного канала (в том числе) и одновременно по нескольким каналам (в том числе, дублирование или повышение скорости). Парсер должен быть принципиально независающим. Т.е. он может иметь неопределенное состояние некоторое максимальное количество принятых символов (включили прием посреди передачи), но потом должен "прочухаться". Кодирование от ошибок на более низком уровне. На уровне рассматриваемого кодирования мы проверяем только границы пакетов, полей, CRC. Декодер потока должен быть простым, с оптимизацией по скорости и (или) по объему памяти. В основном табличная реализация, со сдвигом значения в выходном "аккумуляторе", где формируется итоговый поток. Алфавит - 256 символов. -- 128 символов - для передачи 7 бит -- 64 символа для передачи 6 бит (типа MIME). Возможно, лишнее. -- 16+16=32 символа для передачи 4 младших и 4 старших бит -- 32 служебных символа. Поле 8 бит - 4+4 бита, либо 7+7 бит, с кодом Хеминга 16 бит - 7+7+7, с ECC или четностью 24 бита - 7+7+7+7 32 бита - 5*7 48 бит - 7*7 64 бита - 10*7 нестандартные поля - кратно 7 битам. 14 бит, 21 бит, 28 - нестандартные целочисленные переменные. Лишние биты либо отбрасываются, либо используются по усмотрению ПО. Структура пакета. -- старт пакета -- логический уровень в канале, он же приоритет -- максимальная длина или точная длина -- маркер поля : поле -- маркер CRC -- конец пакета Многопоточность -- идет длинный пакет -- у нас "срочность" -- маркер повышения уровня пакета -- начало пакета -- конец "врезанного пакета" -- остаток прерванного пакета. -- максимальная глубина стека прерываний (повышений уровня) - глобальная константа проекта. Параллельная передача по разным каналам. -- вводится идентификатор пакета,адрес отправителя и получателя. -- сокеты. Каждое устройство имеет 256 сокетов Подтверждения. -- все пакеты подтверждаются. Одиночно или группой - параметры соединения. -- подтверждение имеет специальный формат: маркер потдверждения, поле что подтверждаем, марке завершения подтверждения. -- подтверждение выдается в канал в поток, втискиваясь в поток символов. Если уровень позволяет - нельзя прерывать поток более высокого уровня. Контроль канала -- IDLE символ. Кидается в пустой канал не реже чем -- CONTINUE - набор символов. В длинное поле не реже чем вставляется специальный символ, их несколько, они меняются по специальному алгоритму. Чтобы парсер знал, что он не мусор слушает. -- максимальное количество "битовых" символов подряд. Далее либо служебные символы поля и пакета, либо CONTINUE Версии, исключения. -- есть общее понятие версии, есть понятие уровня реализации -- на простых уровнях реализации некоторые фичи опущены, чтобы у "8051" хватило памяти и скорости, условно. Переменная длина. -- при начале пакета или поля мы можем не знать его длину -- оно она не боле чем - вариант поля длины -- позволяет избежать буферизации: по мере приема чего-то от реального устройства пихаем данные в канал по мере поступления. CRC -- параметр соединения. Где-то надо (UART), где-то нет (поверх TCP сокета). Преимущества: -- небольшой и фиксированный оверхед -- полная асинхронность: другая сторона в любой момент может подтвердить или отказать в чем то. -- применимость к любым каналам связи. В частности, TCP не сохраняет гранулярность. Кинули в сокет группу байтов - на выходе может быть несколько пакетов группками -- полный контроль канала. Легко понять, что "что-то пошло не так". -- универсальная библиотека работы с протоколом. Для всех платформ. Для всех каналов связи (кроме особых случаев - высокоскоростной низколатентный канал и т.д.) -- единый парсер для прослушивания и отладки. Критика?