Jump to content

    
Sign in to follow this  
interrupt

Поиск команды в массиве данных

Recommended Posts

Вам подойдет поиск по Регулярным Выражениям. Из всех ваших команд делается 1 регулярное выражение, из которого строится конечный автомат. Он (автомат) запускается на входной поток символов и выдает все совпадения за 1 проход над входной строкой (на лету)

Если вас устроит готовый парсер можете посмотреть в сторону flex - он генерирует готовый автомат

 

Да ладно... шаз мы будем рассказывать, что надо использовать Lexx, YACC, perfect hash, поиск по boyes moore, лексический анализ и прочие страшные вещи.. а потом выяснится, что у ТС команды сыпятся по 1200 8N1, обработка идет на двухядерном арме, и вся эта оптимизация с экономией тактов нафиг не нужна :)

Edited by CrimsonPig

Share this post


Link to post
Share on other sites
а потом выяснится, что у ТС команды сыпятся по 1200 8N1, обработка идет на двухядерном арме, и вся эта оптимизация с экономией тактов нафиг не нужна :)
Видимо нужна, иначе бы ТС с этот вопрос не задавал

Да ладно... шаз мы будем рассказывать, что надо использовать Lexx, ... лексический анализ и прочие страшные вещи..
Они не такие страшные. Что бы воспользоваться flex'ом совсем не обязательно писать его (flex) самому - можно взять готовый :rolleyes: А уж команды для flex'а написать в виде regexp'ов и вовсе простое дело :beer:

 

Share this post


Link to post
Share on other sites
Видимо нужна, иначе бы ТС с этот вопрос не задавал

 

Гы, тут ы соседнем топике есть товарищ.. уже полгода пытается оптимизировать код с точностью до такта, чтоб работало быстрее и потребляло меньше, только вот цикл while правильно до сих пор написать не может :)

Share this post


Link to post
Share on other sites

За советы спасибо.

 

По поводу скорости. Обмен идет на 115200, обработка на STM32F100. Кроме этого контроллер загружен другими интерфейсами, обработкой прерываний, АЦП ну и т.п. Поэтому оптимизация времени обработки строки вроде бы актуальна.

 

Насчет AT команд. Ну примерно к этому и иду, но не понимаю, как их быстро разбирать. Ну вот есть у GSM-модуля огромный список этих команд. Контроллер выплевывает в него одну из них. Как он находит соответствие из всего перечня команд? Была у меня и такая мысль, делать группы команд, просто через обычный "if". Но получается очень громоздко и сложно при добавлении новых команд.

Share this post


Link to post
Share on other sites
Такая задача. Контроллер принимает по UART некоторые данные в виде строк разной длины и содержания. Т.е. обычные текстовые строки. В этих строках может содержаться команда для контроллера, например: Switсh on out 7, input 1 disable, Led 11 on.

............

Если известна максимальная длина команды, то в обработчике прерыввания можно сделать буфер FIFO той же длины и с каждым входящим байтом анализировать именно это окно, а не весь массив. В GSM-модеме в конце каждой команды следует байт 0x0D, по которому обработчик прерывания устанавливает флаг, что принята команда и FIFO буфер нужно скопировать для последующего неспешного анализа, чтобы следующие приходящие байты не помешали. Если крутится операционка, то прерывание по определённому символу выдаёт семафор соответствующей задаче. Как-то так мне это представляется.

 

Share this post


Link to post
Share on other sites
Похоже, в точку. Только пока не нашел, как это реализовать. Буду копать.

Там все гораздо проще - простой перебор :)

По первому символу после сочетания "AT" определяется класс команды, а потом в соответствующей таблице ищется требуемая запись

80_VF696_1_B_AT_Command_Set_AMSS.pdf

Edited by Harvester

Share this post


Link to post
Share on other sites

привет,

 

особо не вдавался в советы форумчан (прочитал только первый пост)

 

вот кусок кода с ATMega (обработка прерывания)

int Flag_Sign_1 = NO;

int Flag_Sgn_OK = NO;

int Flag_Addr_Comm = NO;

char AddrCommand;

char Data;

 

ISR(USART_RXC_vect)

{

unsigned char RX_Data;

RX_Data = UDR;

if (RX_Data == 0xAA && Flag_Sign_1 == NO) // первая фаза получения сигнатуры

{

Flag_Sign_1 = YES;

return;

}

if (RX_Data == 0x55 && Flag_Sign_1 == YES) // вторая(конечная) фаза получения сигнатуры

{

Flag_Sgn_OK = YES;

return;

}

if (Flag_Sgn_OK = YES) // сигнатура принята переходим к декодированию адреса - команд - данных

{

if (Flag_Addr_Comm == NO) // получаем адрес - команду

{

Flag_Addr_Comm = YES;

AddrCommand = RX_Data;

return;

}

else // получаем данные и отправляем на декодирование

{

Data = RX_Data;

Decoder(AddrCommand, Data);

Flag_Addr_Comm = NO;

}

}

Flag_Sign_1 = NO;

Flag_Sgn_OK = NO;

}

 

YES и NO определены через define

 

в принципе из кода всё ясно, но если есть какие вопросы отвечу.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this