Определение начала пакета данных ?

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Определение начала пакета данных ?

Сообщение FUZZY_ »

имеется прерывание приема передачи которое ложит принятые байты в буфер Uchar bufrd[255];
обычно байты приходят по 2-3 число пришедших байт в Uchar btr; данные идут нерерывно с интервалом 20 mc

пакет данных начинается с кодов в диапазоне {0x80...0x8A }, { 0xC0...0xCA } декодирование пакета, его длина б контрольная сумма однозначно определена спецификацией интерфейса

перед пакетом может быть от 0 до 10 байт - которое относится к маршрутизации пакета данных и для меня интереса не представляет
(величина размера случайная)
0 - пакет данных идет без маршрутизации

typedef unsigned char Uchar;
Uchar bufrd[255];
Uchar btr;

Вопрос как правильно соблюсти условиядля максимального быстродействия приема начала пакета данных ?

Помогите советом
Saadov
Нашел транзистор. Понюхал.
Сообщения: 155
Зарегистрирован: Вт авг 19, 2008 23:39:59
Откуда: г.Смоленск

Re: Определение начала пакета данных ?

Сообщение Saadov »

Советую прочитать статью "Спецификация протокола WAKE"
http://caxapa.ru/lib/wake/
В статье подробно все описано, даны исходники С,ASM, код для ПК и много всего.
Возможно натолкнет вас на мысль.
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Re: Определение начала пакета данных ?

Сообщение FUZZY_ »

Не подходит , там фиксированая преамбула а у меня плавает 0т 0 до 10 бaйт

C2 17 24 34 34 cs = 0 бaйт маршрутизации

00 80 17 24 40 Nx cs = 1 бaйт маршрутизации

55 56 57 58 8a 81 17 24 81 cs = 5 бaйт маршрутизации

и много много других комбинаций с преамбулой от 0 до 10 бaйт
Вложения
wake.jpg
(17 КБ) 615 скачиваний
Последний раз редактировалось FUZZY_ Вт авг 10, 2010 22:03:07, всего редактировалось 1 раз.
Saadov
Нашел транзистор. Понюхал.
Сообщения: 155
Зарегистрирован: Вт авг 19, 2008 23:39:59
Откуда: г.Смоленск

Re: Определение начала пакета данных ?

Сообщение Saadov »

Я после работы туго соображаю. Но преамбула показывает код операции, например, а у вас преамбулу еще надо поймать. Как то это не понятно.
C2 17 24 34 34 cs = 0 bit маршрутизации

00 80 17 24 40 Nx cs = 1 bit маршрутизации

55 56 57 58 8a 81 17 24 81 cs = 5 bit маршрутизации

и много много других комбинаций с преамбулой от 0 до 10 bit


бит или байт??
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Re: Определение начала пакета данных ?

Сообщение FUZZY_ »

Байт конечно, bit - это ошибочно
Saadov
Нашел транзистор. Понюхал.
Сообщения: 155
Зарегистрирован: Вт авг 19, 2008 23:39:59
Откуда: г.Смоленск

Re: Определение начала пакета данных ?

Сообщение Saadov »

Отведите еще один байт под идентификацию, чтобы приняв его устройство сразу знало, что это начало пакета и/или сколько будет по длине преамбула. Я ведь не зря привел вам ссылку на протокол, так как там есть информация по вашему вопросу.
{Идентификатор...Преамбула}{Данные}{CRC}
Например, старший нибл кол-во байт в преамбуле, младший, что делать устройству, ну или наоборот.
Аватара пользователя
Pooher
Мучитель микросхем
Сообщения: 491
Зарегистрирован: Вс янв 07, 2007 01:45:48
Откуда: Российская Федерация, будь она неладна...

Re: Определение начала пакета данных ?

Сообщение Pooher »

А что мешает в начало пакета добавить, скажем, 2 байта которые будут однозначно определять условие?
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Re: Определение начала пакета данных ?

Сообщение FUZZY_ »

данные отсылает устройство на работу я повлиять никак не могу
Моя задача принять данные и расшифровать предаваемую команду


55 56 57 58 8a - это надо отсечь
81 17 24 81 cs - это надо принять cs- это контрольная сумма посылки которая принимается

f0 - это надо отсечь
81 17 24 81 cs - это надо принять

00 - это надо отсечь
81 17 24 81 cs - это надо принять

пример передачи одной и тойже команды команды (81 17 24 81 cs)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Определение начала пакета данных ?

Сообщение Kavka »

пакет данных начинается с кодов в диапазоне {0x80...0x8A }, { 0xC0...0xCA }

55 56 57 58 8a - это надо отсечь
81 17 24 81 cs - это надо принять cs- это контрольная сумма посылки которая принимается

его длина б контрольная сумма однозначно определена спецификацией интерфейса

Чёт у вас неточности в примерах и вопросе.

Возникает логичный вопрос - а внутри пакета возможны те коды с которых вы указали возможное начало пакета?
Если нет, то это тоже упрощает задачу.

А вообще, вижу два варианта.
1) Принимать поток вы начинаете с известного места - с паузы между пакетами.
Тогда у вас будет простейший конечный автомат (он же state machine по буржуйски) ждущий пока не попадётся байт начала пакета, т.е. пропускающий маршрутную информацию.
Дальше всё просто.

2) Принимать поток вы начинаете с произвольного места.
Тогда надо хранить последние 6 байт и по поступлению каждого нового байта проверять условие по контрольной сумме, начальному байту и структуре пакета данных. При выполнении условий вы получаете пакет данных.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
Pavel V.
Мявтор!
Сообщения: 384
Зарегистрирован: Ср май 17, 2006 18:39:01
Откуда: Москва
Контактная информация:

Re: Определение начала пакета данных ?

Сообщение Pavel V. »

Выкладывай нормальное описание протокола, придумаем что-нибудь :) Наверняка к этой железяке есть мануал.
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Re: Определение начала пакета данных ?

Сообщение FUZZY_ »

Pavel V. писал(а):Выкладывай нормальное описание протокола, придумаем что-нибудь :) Наверняка к этой железяке есть мануал.


Вот логи протокола


Вот перевод с китайского

Link слоя:
Формат блока:
Запрос:
Fmt TargetAdr + + + SourceAdr Сид + Data + CS
Fmt: 1BYTE, 0x80 плюс длина значения Com и ComInfo
TargetAdr / SourceAdr: адреса назначения / адрес источника 1BYTE
Sid: 1BYTE идентификатор команды
Данные: 0 байт или больше байт команду информации
CS: число байт 1BYTE контрольной накапливаются, и проверить
Ответ:
Fmt TargetAdr + + + SourceAdr Сид + Data + CS
Sid: 1BYTE команды, ЭКЮ ответить, когда байт содержание оборудования просил команду ID + OX40
Уровень приложений:
Чтение информации о версии:
Версии информацию для ответа на ключевые слова F6 после первого кадра первого байта старший бит равен 0, если ситуация: 0F 01 F6 +31 4A ... ... 03
Версии информацию для ответа на ключевые слова F6 после первого кадра первого байта старший бит ситуации, нынешнего положения, прочитав предыдущую версию информация, затем будут сделаны 03 XX 00 03 читать дополнительные значения, пока Совет Первый кадр из ключевых слов, первый байт после самого высокого уровня от 0 до.
Система ввести команду:
82 28 f1 10 89 34
Читает информацию о версии:
82 28 f1 1a 9B 50
Ссылка для поддержания:
82 28 f1 3E d8



С код работает приблизительно 50 на 40 10 - не фильтрует вообще

if(!begin){


//----------
if((bufrd[0]==0)&(btr==1)) return;

else {

p=bufrd; ip=btr;
for(cnt=0; cnt<btr; cnt++) {

if ( (unsigned int )p[0] < 0x80 ) {p++; ip--; }
//----------
else {

if( (unsigned int )p[0] > 0x8A ) {

//----------

if( ( (unsigned int )p[0] >= 0xC0 )||((unsigned int )p[0] <= 0xCF)) {
/* oт C0 до CF начало посылки */
memcpy(Pwork,bufrd,btr);
Pwork+=btr; cb+=btr;
begin=true; // return;
}

else {p++; ip--; }
//----------
}
else {
/*от 80 до 8A начало посылки*/
memcpy(Pwork,bufrd,btr);
Pwork+=btr; cb+=btr;
begin=true;


}
}
};



if( (p!=bufrd)&&(ip>0)) {
if((work[0]&0xc0==0xc0)|| (work[0]&0xc0==0x80)){

memcpy(Pwork,p,ip);
Pwork+=ip; cb+=ip;
begin=true; }

};

// Sleep(15);

} //else
} //end begin
else {
memcpy(Pwork,bufrd,btr);
Pwork+=btr; cb+=btr;

if(cb>4){


switch(work[0]){
case 0x80:
case 0xC0: len= (work[3] +5); break;
default: len=(work[0]&0x3F) +4; break; //определение всей длины пакета
};

/* тут и есть штопор если cb==len то все ок но если cb>len потеря синхронизации и крах декодирования */
if(cb>=len) { Analiz(); ToInit(); // расшифровка команды

}

if (cb>15) ToInit(); // Это выход из зависания


};


}
}
Вложения
view.jpg
(8.79 КБ) 545 скачиваний
p.rar
(2.71 КБ) 161 скачивание
Pe3ucTop
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пт ноя 16, 2007 13:52:44
Откуда: Рига, Латвия

Re: Определение начала пакета данных ?

Сообщение Pe3ucTop »

В вашем случае очень хорошая ситуация для сокращения кода :)
8x и Cx - отличаются одним битом :) т.е. делаем операцию OR ( | 0x40 ) , и получаем диапазон Cx .. для которого делаем две проверки... >=C0 <=CA... ну или бинарными действиями, не суть..
Вопрос зачем у вас преобразование (unsigned int )p[] ?? мне кажется тогда уж правилнее к (unsigned char )p[] , если это не обходимо..

И не очень понял - вы хотите работать уже с буфером или на прямую с принимаемыми данными ??
И правильно ли я понял - вы не можете постоянно следить за принимаемыми данными, т.е. программа отлучается на обработку памяти ..
Просто из вашего сообщения показалось что прерывание для того что-бы копировать теже данные одним пакетом в 256 , хотя правильнее наверно по одмому при приёме, или уже по размеру пакета..

А прерыватся наверное лучше после приёма пакета :) или 10-ти пакетов, смотря на как долго надо прерыватся..

Да и программа у вас выдрана кусками, многое не понятно: первая половина понятна, вторая прям белиберда какая-то, не фватает коментариев :)
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Re: Определение начала пакета данных ?

Сообщение asteroid7 »

FUZZY_, одного сравнения

Код: Выделить всё

if ( ( ( b >= 0x80 ) && ( b <= 0x8A ) ) || ( ( b >= 0xC0 ) && ( b <= 0xCA ) ) ) { ...
недостаточно. Кстати, в приведённом вашем коде такого условия нет.

Полином контрольной суммы известен? Контрольная сумма чего? нужных шести байт или всех принятых?
По подсчитанному КС надо дополнительно проверять пакет.
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Re: Определение начала пакета данных ?

Сообщение FUZZY_ »

Вот как должно обрабатываться сообщение:

Пришли данные: 55 56 57 AA F0 82 C0 F0 18 00 4A

Код 55 56 57 AA F0 - должен отброситься

код должен приняться 82 C0 F0 18 00 4A,

где 82 - заголовок, по заголовку мы узнаем количество байт которые нужно принять,

LEN=(количество байт команды) (0x82 - 0x80) +(2 байта адреса ) +( 1 байт контрольной суммы) = 2 +2 +1 =5 ( после 82 мы дожна принять еще 5 байт)


* при количестве байт команды больше 63 имеем вид

[ 80 ] [2 байта внутреней адресации ] [1 байт - количество байт команды] [ n байт команды (оговореных выше)] [1 байт контрольной суммы]

LEN = 2+1+1+n;


С0 F0 - внутрення адресация

18 00 - 2 байта команды

4A - контрольная сумма (usigned char) CS= 82 + C0 + F0 + 18 + 00

аналогично и с кодом С0
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Re: Определение начала пакета данных ?

Сообщение FUZZY_ »

Вот правленный код


if (!begin) {

if((bufrd[0]==0)&(btr==1)) return; //если пришел 1 байт и он = 0

cb=0;

for(cnt=0; cnt<btr; cnt++) {


if ( ( b >= 0x80 ) && ( b <= 0x8A ) ) { //диапазон 0x80 - 0x8A

memcpy(Pwork,bufrd + cnt ,btr -cnt );

Pwork+=btr-cnt; // указатель на хвост буфера

cb+=btr-cnt;

begin=true;

return ;


}

else{


if ( ( b >= 0xC0 ) && ( b <= 0xCA ) ) { // диапазон С0 - СA

memcpy(Pwork,bufrd + cnt ,btr -cnt );

Pwork+=btr-cnt; // указатель на хвост буфера
cb+=btr-cnt;

begin=true;

return ;



}

else{ //все значения которые не вошли в диапазаны 0x80 - 0x8A , С0 - СA

cb+=0;
begin=false;

}; /* конец проверки диапазана С0 - СA * /

} ; /* конец проверки диапазана 0x80 - 0x8A * /

}


} /* end begin */

else {

memcpy(Pwork,bufrd,btr);
Pwork+=btr;

if(cb>4){
switch(work[0]){
case 0x80:
case 0xC0: len= (work[3] +5); break;

default: len=(work[0]&0x3F) +4; break; //определение всей длины пакета

}

if(cb==len) {
Analiz(); ToInit(); // расшифровка команды

}

if (cb>15) ToInit(); // Это выход из зависания


}
else return;
Pe3ucTop
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пт ноя 16, 2007 13:52:44
Откуда: Рига, Латвия

Re: Определение начала пакета данных ?

Сообщение Pe3ucTop »

Опять неточности:
здесь размер до 10 байт.
//диапазон 0x80 - 0x8A

здесь уже упоминается 63 :) ,
где 82 - заголовок, по заголовку мы узнаем количество байт которые нужно принять,
LEN=(количество байт команды) (0x82 - 0x80) +(2 байта адреса ) +( 1 байт контрольной суммы) = 2 +2 +1 =5 ( после 82 мы дожна принять еще 5 байт)
* при количестве байт команды больше 63 имеем вид

А здесь уже 63 в коде присутствуют ( 0x3F ), хотя зачем если диапазон в том же коде ограничен маской 0x0F ...
default: len=(work[0]&0x3F) +4; break; //определение всей длины пакета

Получается - диапозоны :
0x80 - 0xBF
0xC0 - 0xFF

И опять таки - определяющим остаётся один бит для диапазонов , и один бит для определения нужного диапазона, а остальные - размер..
0b1Dss ssss , где - первая еденица, сравнение принадлежнсоть к диапазонам, D - определяет диапазон , ss ssss - определяет размер - 0...63 ..

Сравнений - излишки !!

Код возможно выложу позже, а ведь так лень за когото переделывать :D

Ошибки в алгоритме (по куску кода, что дан):
- в буфере может быть только чать пакета , и вы только с ней будете оперировать
- приём может начатся с середины пакета, если вклинится в приём, и в данных пакета будет байты Ваших заголовков..
- что-то мне подсказывает, что если пакет больше 15 , он вообще не будет обрабатыватся :)
- не ясно - каких размеров у вас буферы ??
- не ясно - каким образом сбрасывается буфер или сдвигается по кругу и т.п.
- некоторые переменные - не понятны : (b , cb , work[])
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Re: Определение начала пакета данных ?

Сообщение FUZZY_ »

* при количестве байт команды больше 63 имеем вид

[ 80 ] [2 байта внутреней адресации ] [1 байт - количество байт команды] [ n байт команды (оговореных выше)] [1 байт контрольной суммы]

LEN = 2+1+1+n;

Это общий стандарт протокола ( ответ на запрос) , в моем случае я никогда не буду принимать пакет больше 15 , так как обрабатываю только
запросы.

#define BUFSIZE 255

Uchar work[BUFSIZE]; //буфер обрабатываемой команды тут лежит только нужные нам байты
cb - количество байт принимаемой команды


btr -количество байт в приемном буфере на момент когда мы к нему обращаемся ( после его чтения он заполнтся с 0 позиции)



Uchar bufrd[BUFSIZE]; // приемный буфер


Pwork=work; // в самом начале или после обработки команды

Например

код должен приняться 82 C0 F0 18 00 4A,

Расположение в буфере
work[0]=0x82
work[1]=0xC0
work[2]=0xF0
work[3]=0x18
work[4]=0x00
work[5]=0x4A
work[6]=0
work[..]=0
work[255]=0
FUZZY_
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Re: Определение начала пакета данных ?

Сообщение FUZZY_ »

http://www.cplusplus.com/reference/stl/deque/

Кусок рабочей программы на С++ , как перевести для МК в части с deque



unsigned int cnt;


deque <unsigned char> msg;


for(cnt=0;cnt<btr;cnt++) {

msg.push_back(bufrd[cnt]);

}


//----------
cb+=btr;

if( (msg.front()&0x80)!=0x80 ) {

for(cnt=0; cnt< msg.size(); cnt++) {


if( ((msg[cnt]>=0x80)&&(msg[cnt]<0x8A))||((msg[cnt]>=0xC0)&&(msg[cnt]<=0xCA))) {

msg.erase(msg.begin(), msg.begin()+cnt); //удалили элементы которые не соотв условию

break; //вышли из цикла
}
cb--;

}
//----------
}



for(cnt=0;cnt< msg.size(); cnt++) { work[cnt]=msg[cnt]; } //заполнили массив для обработки

//----------
msg.clear();

if(cb>4) {


Form1->StatusBar1->Panels->Items[1]->Text="Start";

//----------
switch(work[0]) { //вычисление длины обрабатываемого сообщения .. тут надо сделать так чтобы оно считало только раз ...
case 0x80:
case 0xC0: len= (work[3] +5); addlen=true; break;
default: len=(work[0]&0x3F) +4; addlen=false; break;
};

//----------
Form1->Edit22->Text=IntToStr((int)len);
//----------

if(cb==len) {
Analiz(); ToInit(); //расшифровка сообщения
Form1->StatusBar1->Panels->Items[1]->Text="Stop";
}

if (cb>15) ToInit(); // если не произошла рашифровка (нет данных в базе данных)


}
else{ Form1->StatusBar1->Panels->Items[1]->Text="Wait"; }
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»