реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Обработка массивов с неполными пакетами
Atlantis-
сообщение Oct 19 2015, 15:02
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102



Здравствуйте!
Никак не соображу, как лучше обрабатывать массивы данных с неполным пакетом в конце. Конкретный пример: на ПК приходит массив данных:
пакет1(16 байт), пакет2(32 байта), неполный пакет (от 1 до 15 байт). Каждый пакет содержит байт, указывающий кол-во данных в пакете
Вроде как надо неполный пакет сохранить и потом склеить во время следующей посылки, а обрабатывать несколько полных пакетов, но как это все вычислить, может кто подскажет?
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 19 2015, 15:15
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Если это ПК, то никто не мешает сделать буфер не из байтов, а из пакетов (длина каждого - максимально возможная по протоколу).
А дальше выгребать из массива побайтно и перекладывать в этот буфер. По окончании буфера запомнить состояние "работаем с пакетом №3, в нём 5 байт из N", при появлении следующего "массива" продолжить разбор.
Буфер из пакетов, само собой, закольцованный.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Oct 19 2015, 15:36
Сообщение #3


Местный
***

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



Цитата(esaulenka @ Oct 19 2015, 16:15) *
Буфер из пакетов, само собой, закольцованный.


А зачем закольцованый ? sm.gif
На самом деле, слишком общий вопрос и и мало данных.. На общий вопрос соответствующий ответ:
- опишите свои пакеты структурой данных (классом) с состоянием (длина, сколько данных в него надо принять до состояния "заполненности" итп)
- организуйте FIFO - очередь пакетов, например, с помощью списка указателей на эти структуры (std::list, например), тогда недопринятый пакет всегда будет в конце списка. Принятые пакеты удаляем с головы.

Кроме этого, возможно реализовать примерно еще 764 других варианта решеня поставленной задачи sm.gif

Сообщение отредактировал CrimsonPig - Oct 19 2015, 15:38
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 19 2015, 15:44
Сообщение #4


Гуру
******

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



QUOTE (Atlantis- @ Oct 19 2015, 18:02) *
...может кто подскажет?

Может для начала подскажете, а в чем "проблема" ?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
megajohn
сообщение Oct 19 2015, 17:30
Сообщение #5


Профессионал
*****

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



Цитата(Atlantis- @ Oct 19 2015, 18:02) *
обрабатывать несколько полных пакетов, но как это все вычислить, может кто подскажет?


дык банально

считать ОДИН БАЙТ "длина пакета"
если УСПЕШНО, то считать N-БАЙТ ( где N это длина пакета )
если УСПЕШНО, то передать в обработку, иначе снова считывать ( пока не будет собран весь пакет )


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Oct 19 2015, 20:15
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(megajohn @ Oct 19 2015, 20:30) *
дык банально


Банально, если протоколом предусмотрено обнаружение начала пакета. Наличие только длины это не обеспечивает.
Так что автор наступил на грабли.
Или временное разделение пакетов, или там STX/ETX и проч.
Надежда, что пакеты засинхронизируются намертво, не работает.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
smalcom
сообщение Oct 19 2015, 20:19
Сообщение #7


Профессионал
*****

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



вообще контрольная сумма у пакета должна быть. если протоколом не предусмотрено, то это хижина глистов.
Go to the top of the page
 
+Quote Post
Atlantis-
сообщение Oct 20 2015, 07:05
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 20 2015, 07:44
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Вы бы хоть формат пакета привели, а то тут сейчас "разведем тучки ручками"
Go to the top of the page
 
+Quote Post
Atlantis-
сообщение Oct 20 2015, 07:50
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
smalcom
сообщение Oct 20 2015, 08:42
Сообщение #11


Профессионал
*****

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



добавьте контрольную сумму и проблема отпадёт
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Oct 20 2015, 09:41
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Atlantis- @ Oct 20 2015, 10:50) *
[0] счетчик
...

Сами то как предполагаете достичь пакетной синхронизации?
Вот включился контроллер, или компьютер, и начал принимать с десятого байта в пакете, и дальше что?

Вот немцы правы - у них принципы передачи данных стандартизованы, время тратится на суть проекта, а не на познание банальных протоколов передачи данных.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Atlantis-
сообщение Oct 20 2015, 10:31
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102



Цитата(Dog Pawlowa @ Oct 20 2015, 12:41) *
Сами то как предполагаете достичь пакетной синхронизации?
Вот включился контроллер, или компьютер, и начал принимать с десятого байта в пакете, и дальше что?

Вот немцы правы - у них принципы передачи данных стандартизованы, время тратится на суть проекта, а не на познание банальных протоколов передачи данных.

У меня никогда такого не было, чтобы не с первого принимал... А каким образом можно засинхронизироваться? И о каких принципах речь?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Oct 20 2015, 10:47
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Atlantis- @ Oct 20 2015, 13:31) *
А каким образом можно засинхронизироваться? И о каких принципах речь?

Ну самый примитивный стандартный протокол STX текст ETX checksum тайм-аут
Переводите свои данные в текст, обрамляете служебными символами STX/ETX и добавляете контрольную сумму.
Приемник знает, как однозначно найти начало и конец пакета.
Даже если начал принимать с середины, сможет отбросить мусор.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
mcheb
сообщение Oct 20 2015, 10:48
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602



Цитата(Atlantis- @ Oct 20 2015, 13:31) *
У меня никогда такого не было, чтобы не с первого принимал... А каким образом можно засинхронизироваться? И о каких принципах речь?

http://electronix.ru/forum/index.php?showtopic=130550
Форум надо читать, а не только писать
Go to the top of the page
 
+Quote Post
Atlantis-
сообщение Oct 20 2015, 14:59
Сообщение #16


Местный
***

Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102



Цитата(mcheb @ Oct 20 2015, 13:48) *
http://electronix.ru/forum/index.php?showtopic=130550
Форум надо читать, а не только писать

Спасибо за ссылку. Но меня пока другой вопрос беспокоит...
Переделал пакеты так, что в нулевом байте теперь общее кол-во данных.
Сделал по принципу
Цитата
считать ОДИН БАЙТ "длина пакета"
если УСПЕШНО, то считать N-БАЙТ ( где N это длина пакета )
если УСПЕШНО, то передать в обработку, иначе снова считывать ( пока не будет собран весь пакет )


на самом деле сделал еще один массив. если в нем остается неполный буфер, то переписываю его в начало этого массива, а потом копирую туда же приемный буфер. вроде бы должно работать...и работает, но сбивается через разное время...беда
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 20 2015, 15:26
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Вот так попробуйте

[STX][LEN][DATA][CRC]

STX - какой-то байт, например FA
его и парсим из буфера, пока не наткнемся
потом читаем [LEN] и вычитываем длину данных [DATA]
вычитываем [CRC] и сравниваем с рассчитанной

откуда считать CRC - тут уж как Вам угодно. Или всего пакета, или только [DATA]
как считать CRC - тут тоже все зависит от размера пакета. От простого XOR до CRC32
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Oct 20 2015, 15:33
Сообщение #18


Местный
***

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



Цитата(Atlantis- @ Oct 20 2015, 15:59) *
на самом деле сделал еще один массив. если в нем остается неполный буфер, то переписываю его в начало этого массива, а потом копирую туда же приемный буфер. вроде бы должно работать...и работает, но сбивается через разное время...беда


кстати, есть такое понятие, как flow control. Что вы будете делать, когда отправляющая сторона шлет данные слегка быстрее, чем принимающая сторона их обрабатывает ?
Go to the top of the page
 
+Quote Post
smalcom
сообщение Oct 20 2015, 15:42
Сообщение #19


Профессионал
*****

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



Цитата
так, что в нулевом байте теперь общее кол-во данных.

возникла помеха, пришёл 0xFE. Каковы действия вашей программы? ))))
А также как она потом снова синхронизируется на начало пакета?
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Oct 20 2015, 15:49
Сообщение #20


Местный
***

Группа: Участник
Сообщений: 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


Очень хорошо. Только вот при удачном сбое можно потерять синхронизацию _навсегда_ sm.gif
Пример: начали принимать с середины пакета, до первого байта [STX], который оказался частью случайных данных. Теперь читаем [LEN] байт, [LEN] при этом мусор, потому что тоже часть данных, а не заголовка пакета. [CRC] низачто не совпадает. И по кругу теперь до скончания времен.
Не даром люди напридумывали всяких дурацких протоколов с байтстаффиггом и прочими неинтересными вещами, правда ?

Go to the top of the page
 
+Quote Post
smalcom
сообщение Oct 20 2015, 16:51
Сообщение #21


Профессионал
*****

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



Цитата
Теперь читаем [LEN] байт

интересно, а кто это так делает? Обыно процедура следующая.
Читаем заголовок, читаем длину, подбиваем контрольную сумму. Не совпало - вернулись на следующий байт после бывшего заголовка и повторяем процедурку.

Цитата
байтстаффиггом

придуман для других целей, связанных с аппаратурой.
Go to the top of the page
 
+Quote Post
Atlantis-
сообщение Oct 20 2015, 16:54
Сообщение #22


Местный
***

Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102



У меня сложная система, 8 микроконтроллеров (1) считывают данные с датчиков, передают их на другой МК (2), тот передает на USB МК (3) и дальше, по изохронному каналу, в ПК. Раз уж пошел такой разговор, какой протокол лучше сделать? В настоящий момент у меня контрольная сумма считается после приема данных от датчиков (1-й МК), там же, кстати, добавляется начало пакета и конец пакета. 2-й МК может отправить данные 3-му от 1, 2, 3, 4 датчиков или может ничего не отправить, если данных нет (частота опроса МК-в номер 1 в два раза меньше). 2-й МК сейчас отправляет посылку, вид которой я привел ранее.
Go to the top of the page
 
+Quote Post
smalcom
сообщение Oct 20 2015, 17:07
Сообщение #23


Профессионал
*****

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



Цитата
какой протокол лучше сделать

если ничего сверхъестественного не нада, то простейший формат уже приведён выше

[STX][LEN][DATA][CRC]

следует учитывать, что CRC8 эффективен при длине пакета где-то до 30-40 байт. При больших размерах нужен CRC16.
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Oct 20 2015, 17:50
Сообщение #24


Практикующий маг
******

Группа: Свой
Сообщений: 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. Так что синхронизация быстро восстанавливается.
Go to the top of the page
 
+Quote Post
Atlantis-
сообщение Nov 11 2015, 07:21
Сообщение #25


Местный
***

Группа: Участник
Сообщений: 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). А количество данных от датчика у меня всегда одинаковое.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Nov 11 2015, 09:33
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Atlantis- @ Nov 11 2015, 10:21) *
А что если размер пакета всегда один и тот же. Можно выкинуть [LEN] ? И ничего страшного, если [STX] будет не одно число, а ряд чисел?
У меня 8 датчиков и я хотел бы на месте [STX] писать номер датчика (1,2,...7,8). А количество данных от датчика у меня всегда одинаковое.

Какое-то дежавю.
STX и ETX(который уже почему-то выкинули) - коды ASCII, не входящие в текст (цифры и буквы).
Соответственно данные должны быть текстом.
Тогда протокол легко и просто обеспечивает выделение пакета, а с помощью контрольной суммы - его правильность.

Выкинуть можно все, просто нужно определить альтернативные правила для выделения пакета. Скажем, тайм-аут.
Или маркеры начала-конца с байт-стаффингом.

Но опять наблюдается потеря логики.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd August 2025 - 19:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01633 секунд с 7
ELECTRONIX ©2004-2016