Перейти к содержанию
    

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

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

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

 

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

Изменено пользователем CrimsonPig

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Видимо нужна, иначе бы ТС с этот вопрос не задавал

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

Похоже, в точку. Только пока не нашел, как это реализовать. Буду копать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Похоже, в точку. Только пока не нашел, как это реализовать. Буду копать.

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

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

80_VF696_1_B_AT_Command_Set_AMSS.pdf

Изменено пользователем Harvester

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

привет,

 

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

 

вот кусок кода с 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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...