|
Опять UART, надоело городить самопальные протоколы |
|
|
|
Mar 14 2016, 11:08
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
Нужно передавать массивы двоичных данных по UART между двумя устройствами.
Так как полезная нагрузка не помещается в пределы 1 байта, необходимо поверх UART использовать некоторый логический протокол, который будет разделять фреймы и как-то управлять потоком.
Следовательно из 256 вариантов байта необходимо зарезервировать несколько значений для признаков начала (или конца) фрейма и, возможно, каких-то других управляющий символов.
Один из вариантов это /xon /xoff. Его минусы в том, что символы /xon /xoff могут встретиться в передаваемых двоичных данных и их надо экранировать. Плюс этого метода в том, что экранирование можно проводить "на лету" при приеме. Промежуточный буфер для этого не требуется.
Второй вариант использовать для кодирования двоичных данных некоторую кодировку. Например, BASE64 или семибитную кодировку, а старшие биты пристегивать отдельным байтом. Тогда символы, не входящие в алфавит BASE64 или со взведенным старшим битом можно считать управляющими. На них можно повесить функции управления протоколом, начала-конца фрейма, повтора передачи, может-быть и адреса устройства и т.п. Обычно кодирование-декодирование требует промежуточного буфера и вносит дополнительные временные издержки.
Так вот, подскажите какие-нибудь популярные реализации логических протоколов поверх UART. Необходимы легковесные протоколы, которые будут работать довольно быстро на Tiny AVR.
Да, желательно без 9-го бита UART, чтобы с PC было проще отлаживаться
Сообщение отредактировал Tsvetik - Mar 14 2016, 11:37
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 36)
|
Mar 14 2016, 11:22
|
Местный
  
Группа: Участник
Сообщений: 465
Регистрация: 13-05-15
Из: Запорожье
Пользователь №: 86 663

|
Цитата(Tsvetik @ Mar 14 2016, 15:08)  ... символы ... могут встретиться в передаваемых двоичных данных и их надо экранировать. Например, начало/конец сообщения обозначить 2-3 символами. И только эта последовательность будет началом/окончанием сообщения. Все символы, входящие в эти последовательности, по отдельности или в другом порядке - есть данные. Управление АТ-командами - вот пример. Начало всегда АТ, а окончание LF, CR.
|
|
|
|
|
Mar 14 2016, 11:32
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
Цитата(Александр1 @ Mar 14 2016, 14:22)  Например, начало/конец сообщения обозначить 2-3 символами. И только эта последовательность будет началом/окончанием сообщения. Все символы, входящие в эти последовательности, по отдельности или в другом порядке - есть данные. Управление АТ-командами - вот пример. Начало всегда АТ, а окончание LF, CR. Те же N символов могут встретиться и в двоичных данных. Например, надо передать AT команду в которой содержится другая AT команда
Сообщение отредактировал Tsvetik - Mar 14 2016, 11:34
|
|
|
|
|
Mar 14 2016, 11:38
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(Tsvetik @ Mar 14 2016, 14:08)  Нужно передавать массивы двоичных данных по UART между двумя устройствами.
....
Так вот, подскажите какие-нибудь популярные реализации логических протоколов поверх UART. Необходимы легковесные протоколы, которые будут работать довольно быстро на Tiny AVR. Стандартно либо передаете данные символьными кодами. А возврат каретки и перевод строки - это конец сообщения. Медленно, т.к. один байт передается двумя посылками, но просто... И годится любая терминалка на хосте... Либо байт-стаффинг. Например WAKE от Ридико... Исходники и описания Леонид выложил... Делать бит-стаффинг нет смысла, т.к. сдвигать массив данных на микроконтроллере долго...
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Mar 14 2016, 11:58
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
За WAKE спасибо.
Сообщение отредактировал Tsvetik - Mar 14 2016, 12:06
|
|
|
|
|
Mar 14 2016, 12:04
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Tsvetik @ Mar 14 2016, 13:08)  Один из вариантов это /xon /xoff. Его минусы в том, что символы /xon /xoff могут встретиться в передаваемых двоичных данных и их надо экранировать. Что вы называете "экранировать", не знаю, но для выделения уникального кода для управления применяется метод байт-стаффинга (byte stuffing). Но отлаживаться с ним неудобно. Обычно для простейших протоколов применяют разделение пакетов по тайм-аутам. Самый простой и удобный метод. А вообще для простеньких применений чаще всего применяют самопальные протоколы. Правда, хороший самопальный протокол можно придумать только при достаточном опыте работы и предварительном написании кучи плохих самопальных протоколов
|
|
|
|
|
Mar 14 2016, 12:20
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
Цитата(Baser @ Mar 14 2016, 15:04)  Что вы называете "экранировать", не знаю, но для выделения уникального кода для управления применяется метод байт-стаффинга (byte stuffing). Но отлаживаться с ним неудобно. Обычно для простейших протоколов применяют разделение пакетов по тайм-аутам. Самый простой и удобный метод. А вообще для простеньких применений чаще всего применяют самопальные протоколы. Правда, хороший самопальный протокол можно придумать только при достаточном опыте работы и предварительном написании кучи плохих самопальных протоколов  Байт-стаффинг и есть экранировать иначе, escape sequence Тайм-ауты нафиг. Медленно и не хочу зависимость от таймера.
|
|
|
|
|
Mar 14 2016, 12:27
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Tsvetik @ Mar 14 2016, 14:20)  Байт-стаффинг и есть экранировать иначе, escape sequence
Тайм-ауты нафиг. Медленно и не хочу зависимость от таймера. Ну так типовая структура любого протокола (набор полей): Стартовый байт Поле адреса Поле длины данных Поле данных Поле CRC На все это накладываете байт-стаффинг для стартового байта. Дальше просто вариации из вышеперечисленного. Но 99% протоколов промышленного применения, что я видел, не применяют байт-стаффинг и используют тайм-ауты
|
|
|
|
|
Mar 14 2016, 12:38
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Baser @ Mar 14 2016, 14:27)  Но 99% протоколов промышленного применения, что я видел, не применяют байт-стаффинг и используют тайм-ауты  Людоеды племени умба-юмба не используют не только таймауты, но и вообще промышленные применения. Темные люди  , как и 99% "промышленных автоматизаторов"  . Ну а таймауты нужны В ЛЮБОМ случае. При том-же байтстаффинге для отработки ошибок использовать таймаут, как аварийное завершение фрейма и по нему-же выброс мусора.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 14 2016, 12:39
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
Цитата(Baser @ Mar 14 2016, 15:27)  Ну так типовая структура любого протокола (набор полей): Стартовый байт Поле адреса Поле длины данных Поле данных Поле CRC На все это накладываете байт-стаффинг для стартового байта. Дальше просто вариации из вышеперечисленного. Но 99% протоколов промышленного применения, что я видел, не применяют байт-стаффинг и используют тайм-ауты  Да вот что-то не нравится мне эта схема вот чем: Длина идет не первым байтом. Если МК с DMA, то нужно будет несколько входов в обработчик прежде чем можно будет включить DMA. Все, что здесь предлагали это какой-то самопал. Неужели нет чего-то более-менее стандартног-популярного? Может, рекомендованного IEC или еще каким-то международным институтом?
Сообщение отредактировал Tsvetik - Mar 14 2016, 12:43
|
|
|
|
|
Mar 14 2016, 12:46
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (iosifk @ Mar 14 2016, 13:38)  Медленно, т.к. один байт передается двумя посылками Сивольные это не обязательно HEX. Можно так-же легко и 3 байта четырьмя символами в стиле UUE, или еще более плотно упаковать. QUOTE (Tsvetik @ Mar 14 2016, 14:39)  Длина идет не первым байтом. Если МК с DMA, то нужно будет... Могу Вас огорчить до "первого байта" Вы с удручающей вероятностью В РЕАЛЬНОЙ ЖИЗНИ сначала отгребете еще мусора. Так что забудьте о том, что есть какой то "первый байт".
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 14 2016, 12:49
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(zltigo @ Mar 14 2016, 14:38)  Людоеды племени умба-юмба не используют не только таймауты, но и вообще промышленные применения. Темные люди  , как и 99% "промышленных автоматизаторов"  . Любите вы, zltigo, туману подпустить в витиеватой форме. Я вот даже не понял, то ли мне улыбаться надо, то ли обижаться Цитата Да вот что-то не нравится мне эта схема вот чем: Длина идет не первым байтом. Если МК с DMA, то нужно будет несколько входов в обработчик прежде чем можно будет включить DMA Я не имел ввиду жесткий порядок полей. Встречал всякие варианты. И первым идет адрес (для мультимастер шины и фиксированной длине пакета) И первым идет длина пакета (для переменной длины пакета и удобства применения ДМА) Вариантов море. Если начнете изучать различные стандартные протоколы, то тоже подивитесь разнообразию вкусов разработчиков... Цитата(zltigo @ Mar 14 2016, 14:46)  Могу Вас огорчить до "первого байта" Вы с удручающей вероятностью В РЕАЛЬНОЙ ЖИЗНИ сначала отгребете еще мусора. Так что забудьте о том, что есть какой то "первый байт". Естественно, если задача предполагает наличие высокого уровня помех, то протокол должен это учитывать. Например разгребать сплошной поток мусора с пакетами после радиомодема. Но там где спешить некуда, можно сделать и попроще...
|
|
|
|
|
Mar 14 2016, 12:52
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
Цитата(zltigo @ Mar 14 2016, 15:46)  Могу Вас огорчить до "первого байта" Вы с удручающей вероятностью В РЕАЛЬНОЙ ЖИЗНИ сначала отгребете еще мусора. Так что забудьте о том, что есть какой то "первый байт". Первый байт фрейма. Считайте, что мусор из приемника уже вычищен, а начало фрейма найдено. Чтобы не было необходимости долго побайтово вычитывать заголовок фрейма, хорошо бы, чтобы длина была как можно ближе к началу фреймаю. В идеале закодирована в первом байте. Цитата(Baser @ Mar 14 2016, 15:49)  Любите вы, zltigo, туману подпустить в витиеватой форме. Я вот даже не понял, то ли мне улыбаться надо, то ли обижаться Я не имел ввиду жесткий порядок полей. Встречал всякие варианты. И первым идет адрес (для мультимастер шины и фиксированной длине пакета) И первым идет длина пакета (для переменной длины пакета и удобства применения ДМА) Вариантов море. Если начнете изучать различные стандартные протоколы, то тоже подивитесь разнообразию вкусов разработчиков... Ну дайте хоть названия-то этих стандартных протоколов. Что изучать, что гуглить?
|
|
|
|
|
Mar 14 2016, 13:11
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Baser @ Mar 14 2016, 14:49)  Я вот даже не понял, то ли мне улыбаться надо, то ли обижаться  Ни то, ни другое - НИКОГДА не ссылаться на "промышленных автоматизаторов" в качестве хоть какого-то авторитета. QUOTE Встречал всякие варианты. И первым идет адрес (для мультимастер шины и фиксированной длине пакета) Адрес идет первым не по причине мультимастера, а по причине быстрого принятия решения по маршрутизации и отсеву при симплексе фреймов по признаку master/slave, котрый тоже закладывается в начальный блок. Наличие во фрейме размера фрейма есть в общем-то моветон, но размер, если уж есть, по любому может быть в любом месте минимального фрейма/заголовка. QUOTE И первым идет длина пакета (для переменной длины пакета и удобства применения ДМА) Про переменную длинну - писал ранее. Про "удобство ДМА", прежде всего следует озаботится тем, что бы НЕ загружать ни DMA ни последующие обработчики приемом и отсеиванием мусора. QUOTE Вариантов море. Глупостей и ошибок всегда можно наделать до бесконечности и еще чуть чуть. Но разумных и продуманно-сбалансированных вариантов ничтожно мало  QUOTE Если начнете изучать различные стандартные протоколы, то тоже подивитесь разнообразию вкусов разработчиков... Для того, что бы понять, как следует стремиться что-то протокольное делать, следует в качестве общего развития понять, как и почему хотя-бы дедушка всех ПРАВИЛЬНЫХ стеков протоколов - X.25 сделан так, как он сделан. После чего уже сможете отделять "вкусы разработчиков" от их дурости безошибочно. QUOTE (Tsvetik @ Mar 14 2016, 14:52)  В идеале закодирована в первом байте. Это НЕ идеал. Это одна узкая точка зрения в вашем случае "ДМА". Как минимум одну причину НЕ иметь размер первым байтом уже назвал.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 14 2016, 13:30
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(Tsvetik @ Mar 14 2016, 15:20)  Байт-стаффинг и есть экранировать иначе, escape sequence А вот давайте не будем придумывать новые термины. Ибо если не знаете протоколов, то и термины применяйте общепринятые... 8b/10b можно даже не обсуждать... Можно поговорить о 9-м бите "чет-нечет", как в MSC51. В микроконтроллере это легко, а вот в хосте не очень...
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Mar 14 2016, 13:33
|

Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 24-04-08
Из: Зеленоград
Пользователь №: 37 056

|
Цитата(zltigo @ Mar 14 2016, 16:11)  Глупостей и ошибок всегда можно наделать до бесконечности и еще чуть чуть. Но разумных и продуманно-сбалансированных вариантов ничтожно мало  Ну так назовите этот самый "разумный". Или это недостижимая мечта вроде коммунизма? Из общеизвестных сходу вспоминаются: MODBUS (ASCII/RTU) SLIP (CSLIP) WAKE ... ?
|
|
|
|
|
Mar 14 2016, 13:58
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(zltigo @ Mar 14 2016, 15:11)  Ни то, ни другое - НИКОГДА не ссылаться на "промышленных автоматизаторов" в качестве хоть какого-то авторитета. Тут я позволю себе обратить вминание на то, что это была моя личная точка зрения основанная на личном практическом опыте: Цитата Но 99% протоколов промышленного применения, что я видел, ... Я не претендую на истинность и не считаю себя большим авторитетом. Ну, да и ладно Цитата(zltigo @ Mar 14 2016, 15:11)  Глупостей и ошибок всегда можно наделать до бесконечности и еще чуть чуть. Но разумных и продуманно-сбалансированных вариантов ничтожно мало  Вот с этим я совершенно согласен. Цитата(Corvus @ Mar 14 2016, 15:33)  Ну так назовите этот самый "разумный". Или это недостижимая мечта вроде коммунизма?  Не возьмусь рекомендовать что-то конкретное, т.к. считаю, что задача и область применения устройства, для которого выбирается протокол, определяет его структуру. Невозможно придумать один универсальный протокол подходящий на все случаи жизни. Случай из жизни. Лет 7 назад мы с коллегой решили разработать новый универсальный протокол для применения в приборах нашей фирмы ( для конкретной области применения, а не вообще), написали свои пожелания, я все продумал, написал проект, обсудили, утвердили. Я его даже реализовал в ОДНОМ макете, который не пошел дальше макета. И все, лежит, уже интегрированый в наши тестовые программы. Всем замечательный протокол, очень гибкий. Но немного сложноват в реализации. Так что мы так и применяем то, что уже применяли на фирме лет 20 - минималистический протокол с коротким фиксированным пакетом. А где нужно больше данных гонять, начали применять по просьбе заказчиков MODBUS, хотя мне и сильно не нравиться его регистровая направленность. Так что не скажу я вам, что ОБЯЗАТЕЛЬНО нужно изучать. Я просто по работе сталкивался то с одним, то с другим протоколом, так и нахватался отрывистых знаний. Теоретического курса по протоколостроению никогда не слушал.
|
|
|
|
|
Mar 14 2016, 14:17
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Baser @ Mar 14 2016, 15:58)  Тут я позволю себе обратить вминание на то, что это была моя личная точка зрения основанная на личном практическом опыте: Я, естественно, тоже писал по своему опыту. QUOTE Невозможно придумать один универсальный протокол подходящий на все случаи жизни. Но ПОДХОДЫ к созданию протоколов должны быть универсальными. Рожать протоколы по принципу у меня тут DMA и ему будет удобнее..., есть неправильно. Любой протокол требует определенных компромиссов. В данном случае вообще Автором намечатся использование DMA через анус - типа я буду разгребать побайтно мусор и искать начало, а потом получив ОДИН байт, который тоже, между прочим, может быть мусором, как запущу DMA, да как получу целую кучу всего, да как потом начну разбираться в том, что получил, и в том числе опять искать в принятом начало фрейма, если размер оказался мусором... В общем фигня  зачем-то поставленая во главу протокола. QUOTE (Corvus @ Mar 14 2016, 15:33)  Ну так назовите этот самый "разумный". Или это недостижимая мечта вроде коммунизма?  Совет, какой смотреть и вникать в ОБЩИЕ принципы многоуровневого построения протоколов, уже был. QUOTE Из общеизвестных сходу вспоминаются: MODBUS (ASCII/RTU) Тихий ужас. ASCII хоть фрейминг имеет, правда огромной ценой. QUOTE SLIP (CSLIP) Это не пртокол, это фреймер. То есть нижний уровень протокола. Если физический уровень байтовый, то этот фреймер и надо использовать в большинстве случаев, а для 485 - в 98% случаев. QUOTE WAKE Слиповский фреймер с небольшими надстройками в стиле MODBUS. Как прямая альтернатива модбасовскому выкидышу - отлично. На продвинутость, естественно, не перетендует.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 15 2016, 12:59
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(iosifk @ Mar 14 2016, 17:38)  Делать бит-стаффинг нет смысла, т.к. сдвигать массив данных на микроконтроллере долго... Это смотря какой микроконтроллер....  Недавно делал опцию отображения содержимого LCD 320x240x4bpp на МК в окно приложения под виндой. Соответственно - периодическая передача содержимого видеоОЗУ (по обновлению оного) в комп по USB. Просто гнать массив - довольно накладно получалось - порядка ~40кБ. А картинка на LCD - это обычный юзер-интерфейс без пиксельной графики - результат вывода текста + линии/многоугольники и т.п. Сделал сжатие картинки на лету на МК - стало гораздо бодрее Траффик упал в неск. раз и МК не помер. Ресурсов это заняло немного. А сжатие - сплошные манипуляции с битами и преобразование в битовый поток. Хотя МК канеш не AVR - LPC4370 с тактовой до 204МГц  Цитата(Baser @ Mar 14 2016, 18:04)  Обычно для простейших протоколов применяют разделение пакетов по тайм-аутам. Самый простой и удобный метод. Годится только для "железного" UART, коих на ПК практически не осталось. Как только пропускаем эти пакеты через UART-USB - все ваши разделения идут лесом. А если автор захочет этот поток например через GPRS-канал пропустить с его непредсказуемыми задержками???......
|
|
|
|
|
Mar 15 2016, 14:05
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(Tsvetik @ Mar 14 2016, 15:08)  Так вот, подскажите какие-нибудь популярные реализации логических протоколов поверх UART. Необходимы легковесные протоколы, которые будут работать довольно быстро на Tiny AVR. Посмотрите как передают NMEA-строки $GPGGA,.........*AB\r\n Есть стартовая последовательность ($) Тип пакета (если он нужен, GPGGA) Данные. Контрольная сумма сообщения (отделена от тела пакета *, в данном случае xorc сообщения, но может быть crc или lrc в зависимости от требований). Стопова комбинация (\r\n, реально всегда хватает только \r) Защищена от бинарного мусора т.к. передача ведётся в ASCII-кодированных символах. Легко парситься из-за наличия старт-стоповых комбинаций. В вашем случае для передачи бинарных данных можно передавать пары символов '0' '0' == 0x00, 'A' 'F' == 0xaf и т.д. Данные легко декодируются даже на мелкой Tiny13 табличным методом, занимая при этом минимум кода.
|
|
|
|
|
Mar 15 2016, 17:34
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
Цитата(jcxz @ Mar 15 2016, 16:05)  Не смешивайте уровни обработки. Драйвер DMA не должен никак зависеть от протокола в котором передаётся поток. Он вообще ничего не должен знать о протоколе. Программируете DMA на любой удобный размер, запускаете и дополнительно, по таймеру отслеживаете состояние работы DMA, с принудительным завершением и перезапуском при простое принимаемого потока. Ну понятно. Это просто вспомнилось. К месту или не к месту  Ну, с одной стороны tiny, а с другой ARM7 или PC при тестах и отладке. Так что требование к DMA вторично. С одной стороны, когда DMA не знает ничего о протоколе будет легко разделить передачу на различные уровни обработки. С другой стороны, добавление уровней обработки часто означает добавление дополнительных буфферов и сильного увеличения уровня вложенности функций.
|
|
|
|
|
Mar 15 2016, 20:05
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата С одной стороны, когда DMA не знает ничего о протоколе будет легко разделить передачу на различные уровни обработки. С другой стороны, добавление уровней обработки часто означает добавление дополнительных буфферов и сильного увеличения уровня вложенности функций. Опять решения по проектированию протокола получается подгоняются под какие-то детали его реализации с имеющимся на данный момент у вас скиллом программирования. Способ передачи данных между уровнями протокола и кол-во вложенности функций должны определяться уже на этапе проектирования реализации протокола, а не самого протокола. Понимаете? Это то-же самое, о чем говорил zltigo, в его посте про DMA. На вскидку: 1.Буферы там особо могут и не понадобиться.. Всегда можно использовать указатель на буйер, который передается по стеку(читать между функциями). 2.Уровень вложенности функций.... Все это очень будет зависеть от того как именно организован код и что делают те самые функции. ИМХО, сам по себе высокий уровень вложенности редко является проблемой. До тех пор пока в фокусе программиста, при работе с какой-то подсистемой, находится разумный уровень вложенности - все ок. Никого сильно не волнует, что при этом от main() до самой дальней функции в проекте получается 100500 вложений. В больших проектах это кстати неизбежно. Так что это должно быть последнее о чем надо думать при проектировании протокола! А первое о чем надо думать - это какие именно задачи решаются этим протоколом, какие данные передаются, какие требования к помехоустойчивости, какая специфика среды передачи данных и т.д.... Очень может быть, что того-же WAKE вам хватит для начала.
--------------------
The truth is out there...
|
|
|
|
|
Mar 16 2016, 06:01
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Tsvetik @ Mar 15 2016, 23:34)  С одной стороны, когда DMA не знает ничего о протоколе будет легко разделить передачу на различные уровни обработки. С другой стороны, добавление уровней обработки часто означает добавление дополнительных буфферов и сильного увеличения уровня вложенности функций. Не понял - о чём Вы? Сколько каких уровней? Вам же вроде надо только выделять кадры из потока байт (определять границы кадра в потоке байт)? Тут хоть с DMA хоть без (на прерываниях) будет только два процесса: 1-ый пишущий в кольцевой буфер байт; 2-ой - читающий из кольцевого буфера поток байт и разбирающий его на кадры. Всё. Если в этих кадрах у Вас инкапсулирован другой протокол - тогда да - дальше будет уровень парсинга уже его кадров из полученных ранее кадров протокола 1-го уровня. Но у Вас вроде только один протокол без вложенных. Если драйвер UART реализован без DMA: ISR UART пишет принимаемые байты в кольцевой буфер и пингует задачу, читающую этот буфер и парсящую поток байт на кадры. Если с DMA - то же самое: DMA пишет в тот же самый буфер и ISR завершения DMA-транзакции так же пингует задачу парсера. Единственно, что наверное записываемые группы байт будут больше, чем в варианте драйвера по прерываниям. В остальном - никакой разницы. Парсер протокола никак не должен зависеть от реализации драйвера UART и каким образом тот кладёт байты в кольцевой буфер.
|
|
|
|
|
Mar 16 2016, 07:43
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
У меня в одном устройстве используется по приему кольцевой буфер DMA плюс прерывание по совпадению байта, и RFC1055 (SLIP). Основано на том, что в SLIP есть специальный байт "конец фрейма", только по нему и прерываюсь. под FreeRTOS это выглядит замечательно: прерывание добавляет адрес начала нового фрейма в очередь для задачи, которая разбирается с пакетами. А разборки идут уже в самой задаче, которая ждет непустой очереди или таймаута(по таймауту проверяется работоспособность и отсутствие ошибок в работе модуля приема-передачи). Таким образом, удается обеспечить прием не одного фрейма, а многих (сколько влезет в кольцо), если они идут группой и иногда обрабатываются дольше чем начинается новый фрейм. Очень дубово, надежно, и не ест лишних ресурсов.
|
|
|
|
|
Mar 17 2016, 05:26
|

pontificator
     
Группа: Свой
Сообщений: 3 055
Регистрация: 8-02-05
Из: страны Оз
Пользователь №: 2 483

|
Цитата(Tsvetik @ Mar 14 2016, 21:38)  Следовательно из 256 вариантов байта необходимо зарезервировать несколько значений для признаков начала (или конца) фрейма и, возможно, каких-то других управляющий символов. Если массивы не очень большие, не более 255 байт, то проще всего использовать COBS. Тогда появление в потоке 0 будет означать "конец сообщения", этого будет достаточно. COBS можно применять и для длинных сообщений, но тогда продется заводить отдельный буфер для кодирования, ибо в процессе кодирования длина сообщения может немного увеличиваться. А для коротких сообщений заранее известно, что после кодирования COBS длина сообщения увеличится ровно на 1 байт, поэтому можно без дополнительного буфера обойтись.
|
|
|
|
|
Mar 17 2016, 06:35
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
Цитата(=AK= @ Mar 17 2016, 08:26)  Если массивы не очень большие, не более 255 байт, то проще всего использовать COBS. Тогда появление в потоке 0 будет означать "конец сообщения", этого будет достаточно. COBS можно применять и для длинных сообщений, но тогда продется заводить отдельный буфер для кодирования, ибо в процессе кодирования длина сообщения может немного увеличиваться. А для коротких сообщений заранее известно, что после кодирования COBS длина сообщения увеличится ровно на 1 байт, поэтому можно без дополнительного буфера обойтись. СУПЕР!! COBS - это как раз именно то, что мне нужно. и реализация миниатюрнейшая Большое спасибо.
Сообщение отредактировал Tsvetik - Mar 17 2016, 06:37
|
|
|
|
|
Mar 17 2016, 07:31
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-10-06
Пользователь №: 21 663

|
Цитата(AlexandrY @ Mar 17 2016, 10:30)  Однако это кодировка с размножением ошибок. Скверный выбор. Что вы имеете ввиду?
|
|
|
|
|
Mar 17 2016, 07:47
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (AlexandrY @ Mar 17 2016, 09:30)  Однако это кодировка с размножением ошибок. Скверный выбор. Да это как раз проблема равная 0, если в этот фреймер не запихивать данные с избыточным кодированим для восстановления. А вот то, что на лету нельзя кодировать, это уже может для очень многих случаев быть тоскливым. Причем пробегать буфер придется два раза - для контрольной суммы и собственно кодирования. А вообще этот COBS муть голубая - подставив вместо первого байта размер, а вместо последного 0x00 гарантированный таймаут получим привычную хрень, которая первой приходит в голову любому начинающему изобретателю фреймера. Только это будет уже БЕЗ ненужных дополнительных плясок с "кодированием" и с бонусом в виде аварийного выброса неполного фрейма по таймауту.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|