|
Обработка массивов с неполными пакетами |
|
|
|
Oct 19 2015, 15:36
|

Местный
  
Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502

|
Цитата(esaulenka @ Oct 19 2015, 16:15)  Буфер из пакетов, само собой, закольцованный. А зачем закольцованый ?  На самом деле, слишком общий вопрос и и мало данных.. На общий вопрос соответствующий ответ: - опишите свои пакеты структурой данных (классом) с состоянием (длина, сколько данных в него надо принять до состояния "заполненности" итп) - организуйте FIFO - очередь пакетов, например, с помощью списка указателей на эти структуры (std::list, например), тогда недопринятый пакет всегда будет в конце списка. Принятые пакеты удаляем с головы. Кроме этого, возможно реализовать примерно еще 764 других варианта решеня поставленной задачи
Сообщение отредактировал CrimsonPig - Oct 19 2015, 15:38
|
|
|
|
|
Oct 19 2015, 17:30
|

Профессионал
    
Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143

|
Цитата(Atlantis- @ Oct 19 2015, 18:02)  обрабатывать несколько полных пакетов, но как это все вычислить, может кто подскажет? дык банально считать ОДИН БАЙТ "длина пакета" если УСПЕШНО, то считать N-БАЙТ ( где N это длина пакета ) если УСПЕШНО, то передать в обработку, иначе снова считывать ( пока не будет собран весь пакет )
--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
|
|
|
|
|
Oct 19 2015, 20:15
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(megajohn @ Oct 19 2015, 20:30)  дык банально Банально, если протоколом предусмотрено обнаружение начала пакета. Наличие только длины это не обеспечивает. Так что автор наступил на грабли. Или временное разделение пакетов, или там STX/ETX и проч. Надежда, что пакеты засинхронизируются намертво, не работает.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Oct 20 2015, 07:05
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(megajohn @ Oct 19 2015, 20:30)  дык банально
считать ОДИН БАЙТ "длина пакета" если УСПЕШНО, то считать N-БАЙТ ( где N это длина пакета ) если УСПЕШНО, то передать в обработку, иначе снова считывать ( пока не будет собран весь пакет ) так то оно так, но байт "длина пакета" в пакете не первый, поэтому бывает, что в неполном пакете этого байта нет Цитата(esaulenka @ Oct 19 2015, 18:15)  Если это ПК, то никто не мешает сделать буфер не из байтов, а из пакетов (длина каждого - максимально возможная по протоколу). А дальше выгребать из массива побайтно и перекладывать в этот буфер. По окончании буфера запомнить состояние "работаем с пакетом №3, в нём 5 байт из N", при появлении следующего "массива" продолжить разбор. Буфер из пакетов, само собой, закольцованный. В принципе, количество недостающих байт не важно. Из пришедшего буфера надо только выделить целые пакеты и запомнить нецелый, который после обработки переписать в начало. Вот в этом месте у меня и получился затык, как это реализовать на практике. Цитата(zltigo @ Oct 19 2015, 18:44)  Может для начала подскажете, а в чем "проблема" ? В точном определении неполного пакета.
Сообщение отредактировал Atlantis- - Oct 20 2015, 07:27
|
|
|
|
|
Oct 20 2015, 07:50
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(toweroff @ Oct 20 2015, 10:44)  Вы бы хоть формат пакета привели, а то тут сейчас "разведем тучки ручками" [0] счетчик [1] кол-во данных (16, 32, 48, 64...128) [2] номера датчиков [3] данные ... Если данных нет - приходит три нуля.
Сообщение отредактировал Atlantis- - Oct 20 2015, 07:51
|
|
|
|
|
Oct 20 2015, 09:41
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Atlantis- @ Oct 20 2015, 10:50)  [0] счетчик ... Сами то как предполагаете достичь пакетной синхронизации? Вот включился контроллер, или компьютер, и начал принимать с десятого байта в пакете, и дальше что? Вот немцы правы - у них принципы передачи данных стандартизованы, время тратится на суть проекта, а не на познание банальных протоколов передачи данных.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Oct 20 2015, 10:31
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(Dog Pawlowa @ Oct 20 2015, 12:41)  Сами то как предполагаете достичь пакетной синхронизации? Вот включился контроллер, или компьютер, и начал принимать с десятого байта в пакете, и дальше что?
Вот немцы правы - у них принципы передачи данных стандартизованы, время тратится на суть проекта, а не на познание банальных протоколов передачи данных. У меня никогда такого не было, чтобы не с первого принимал... А каким образом можно засинхронизироваться? И о каких принципах речь?
|
|
|
|
|
Oct 20 2015, 10:47
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Atlantis- @ Oct 20 2015, 13:31)  А каким образом можно засинхронизироваться? И о каких принципах речь? Ну самый примитивный стандартный протокол STX текст ETX checksum тайм-аут Переводите свои данные в текст, обрамляете служебными символами STX/ETX и добавляете контрольную сумму. Приемник знает, как однозначно найти начало и конец пакета. Даже если начал принимать с середины, сможет отбросить мусор.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Oct 20 2015, 10:48
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602

|
Цитата(Atlantis- @ Oct 20 2015, 13:31)  У меня никогда такого не было, чтобы не с первого принимал... А каким образом можно засинхронизироваться? И о каких принципах речь? http://electronix.ru/forum/index.php?showtopic=130550Форум надо читать, а не только писать
|
|
|
|
|
Oct 20 2015, 14:59
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(mcheb @ Oct 20 2015, 13:48)  Спасибо за ссылку. Но меня пока другой вопрос беспокоит... Переделал пакеты так, что в нулевом байте теперь общее кол-во данных. Сделал по принципу Цитата считать ОДИН БАЙТ "длина пакета" если УСПЕШНО, то считать N-БАЙТ ( где N это длина пакета ) если УСПЕШНО, то передать в обработку, иначе снова считывать ( пока не будет собран весь пакет ) на самом деле сделал еще один массив. если в нем остается неполный буфер, то переписываю его в начало этого массива, а потом копирую туда же приемный буфер. вроде бы должно работать...и работает, но сбивается через разное время...беда
|
|
|
|
|
Oct 20 2015, 15:49
|

Местный
  
Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502

|
Цитата(toweroff @ Oct 20 2015, 16:26)  [STX][LEN][DATA][CRC]
STX - какой-то байт, например FA его и парсим из буфера, пока не наткнемся потом читаем [LEN] и вычитываем длину данных [DATA] вычитываем [CRC] и сравниваем с рассчитанной
откуда считать CRC - тут уж как Вам угодно. Или всего пакета, или только [DATA] как считать CRC - тут тоже все зависит от размера пакета. От простого XOR до CRC32 Очень хорошо. Только вот при удачном сбое можно потерять синхронизацию _навсегда_  Пример: начали принимать с середины пакета, до первого байта [STX], который оказался частью случайных данных. Теперь читаем [LEN] байт, [LEN] при этом мусор, потому что тоже часть данных, а не заголовка пакета. [CRC] низачто не совпадает. И по кругу теперь до скончания времен. Не даром люди напридумывали всяких дурацких протоколов с байтстаффиггом и прочими неинтересными вещами, правда ?
|
|
|
|
|
Oct 20 2015, 16:51
|

Профессионал
    
Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718

|
Цитата Теперь читаем [LEN] байт интересно, а кто это так делает? Обыно процедура следующая. Читаем заголовок, читаем длину, подбиваем контрольную сумму. Не совпало - вернулись на следующий байт после бывшего заголовка и повторяем процедурку. Цитата байтстаффиггом придуман для других целей, связанных с аппаратурой.
|
|
|
|
|
Oct 20 2015, 16:54
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
У меня сложная система, 8 микроконтроллеров (1) считывают данные с датчиков, передают их на другой МК (2), тот передает на USB МК (3) и дальше, по изохронному каналу, в ПК. Раз уж пошел такой разговор, какой протокол лучше сделать? В настоящий момент у меня контрольная сумма считается после приема данных от датчиков (1-й МК), там же, кстати, добавляется начало пакета и конец пакета. 2-й МК может отправить данные 3-му от 1, 2, 3, 4 датчиков или может ничего не отправить, если данных нет (частота опроса МК-в номер 1 в два раза меньше). 2-й МК сейчас отправляет посылку, вид которой я привел ранее.
|
|
|
|
|
Oct 20 2015, 17:07
|

Профессионал
    
Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718

|
Цитата какой протокол лучше сделать если ничего сверхъестественного не нада, то простейший формат уже приведён выше [STX][LEN][DATA][CRC] следует учитывать, что CRC8 эффективен при длине пакета где-то до 30-40 байт. При больших размерах нужен CRC16.
|
|
|
|
|
Oct 20 2015, 17:50
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(smalcom @ Oct 20 2015, 20:51)  Обыно процедура следующая. Читаем заголовок, читаем длину, подбиваем контрольную сумму. Не совпало - вернулись на следующий байт после бывшего заголовка и повторяем процедурку. Я реализовал немного иначе, структура пакета следующая: SYNCHRO, ADRESS, LENTH, CRC_ZAG, DATA, CRC_DAT. В начале заголовка синхрослово (2 байта) по которому начинаю принимать пакет, потом идет адрес и длина блока данных (LENGTH), всё это завершается CRC_ZAG, которая подтверждает что заголовок и длина (LENGTH) в порядке. Далее принимаем указанную длину данных и завершаем процедуру проверкой второй CRC_DAT. Скажу, что этот протокол с минимальными правками четко работает даже в сильно зашумленном канале радио. Если в начале приема пропустили заголовок пакета и в данных оказалась пара байт совпадающая с SYNCHRO, ошибка будет обнаружена всего лишь через 3 следующих байта -когда будет принят CRC_ZAG (CRC8). Если контр.сумма не совпала просто продолжаем искать во входящем потоке SYNCHRO. Так что синхронизация быстро восстанавливается.
|
|
|
|
|
Nov 11 2015, 07:21
|
Местный
  
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102

|
Цитата(smalcom @ Oct 20 2015, 20:07)  если ничего сверхъестественного не нада, то простейший формат уже приведён выше
[STX][LEN][DATA][CRC]
следует учитывать, что CRC8 эффективен при длине пакета где-то до 30-40 байт. При больших размерах нужен CRC16. А что если размер пакета всегда один и тот же. Можно выкинуть [LEN] ? И ничего страшного, если [STX] будет не одно число, а ряд чисел? У меня 8 датчиков и я хотел бы на месте [STX] писать номер датчика (1,2,...7,8). А количество данных от датчика у меня всегда одинаковое.
|
|
|
|
|
Nov 11 2015, 09:33
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Atlantis- @ Nov 11 2015, 10:21)  А что если размер пакета всегда один и тот же. Можно выкинуть [LEN] ? И ничего страшного, если [STX] будет не одно число, а ряд чисел? У меня 8 датчиков и я хотел бы на месте [STX] писать номер датчика (1,2,...7,8). А количество данных от датчика у меня всегда одинаковое. Какое-то дежавю. STX и ETX(который уже почему-то выкинули) - коды ASCII, не входящие в текст (цифры и буквы). Соответственно данные должны быть текстом. Тогда протокол легко и просто обеспечивает выделение пакета, а с помощью контрольной суммы - его правильность. Выкинуть можно все, просто нужно определить альтернативные правила для выделения пакета. Скажем, тайм-аут. Или маркеры начала-конца с байт-стаффингом. Но опять наблюдается потеря логики.
--------------------
Уходя, оставьте свет...
|
|
|
|
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0
|
|
|