|
Обработка массивов с неполными пакетами |
|
|
|
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, не входящие в текст (цифры и буквы). Соответственно данные должны быть текстом. Тогда протокол легко и просто обеспечивает выделение пакета, а с помощью контрольной суммы - его правильность. Выкинуть можно все, просто нужно определить альтернативные правила для выделения пакета. Скажем, тайм-аут. Или маркеры начала-конца с байт-стаффингом. Но опять наблюдается потеря логики.
--------------------
Уходя, оставьте свет...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|