Цитата(Baser @ Nov 8 2008, 02:23)

А я так и не пойму, как при таком алгоритме можно принимать не только сообщения модема, но еще и данные, которые сыпятся по GPRS-у (или по CSD). Я уже писал об этом тут
рядом.
Не знаю что у вас за железо, но я это реализую на mega128+SIM300C. Чего то для этой парочки не слышал про какую-то ось. Что касается алгоритма обработки, то мой алгоритм отлично работал, до появления сообщения REMOTE IP и данных GPRS. Ведь именно по этому я и создал эту тему.
Тут мне подсказали сделать таймауты. После их добавления наши с вами алгоритмы стали практически близнецами. Сами судите.
У меня тот же кольцевой буфер. Размер его выбран по такому же принципу. Байты ловятся в прерывании по приёму USART. Там же стоит логика, которая отслеживает появления LF по принципу StateMachine. Появилось LF дважды (пока таймер ещё не сработал) - значит в буфере уже лежит что-то осмысленное и можно это обработать. Для всех используемых мною команд можно это использовать. При появлении команд, которые в конце не имеют LF - обработку инициирует срабатывание таймера. После начала обработки, StateMachine возращается в начальное состояние, что бы начинать отлов новых ответов с "нового листа".
Сам же принцип обработки тоже очень похож.
Идём по буферу, сравниваем его содержимое с готовыми шаблонами ответа. Определённые ответы выставляют особые флаги. Например нашли OK - ставим OKfound = true. Если в буфере встречается ERROR или ему подобные, то ставиться ERRORfound=true. Если не нашли нужного шаблона - значит это просто ответ - для него есть флаг ANSWERfound.
Когда есть три таких флага, то после посылки любой комады нужно дождаться либо экстернного вываливания (ERRORfound) либо нужного сочетания ANSWERfound и OKfound.
После того как в буфере обработана инфа, он так же чистится, как и у вас. Перед посылкой новой команды, все флаги сбрасываются.
Может это и покажется диким, но у меня как ни странно всё класно работает. Проверял, тестил сутки - сбоев не было. Отработаны команды поднятия GPRS сервиса, инициализации и приёма звонков, посылки и приёма TCP сообщений.
Алгоритм обработки не падает при вклинивании UNSOLICITED сообщений типа RING или +CMTI. При появлении их появлении, они обрабатываеются, затем в буфере происходит откат указателей и программа продолжает корректное ожидание или обработку прерванной комады - все ок.
Цитата(@Ark @ Nov 8 2008, 04:14)

А Вы не пробовали действовать методом исключения? Получив первый символ, после LF, Вы сразу "отсекаете" из набора возможных сообщений все, начинающиеся с другого символа. Очень часто, после приема первых двух-трех-четырех символов, остается только один возможный вариант ответа. С этого момента, уже можно считать сообщение принятым - выставить флаг, определить код сообщения и переключиться на ожидание следующего LF. C какой задержкой придет оставшаяся часть ответа и завершающий LF (или LF нового сообщения) - уже не будет иметь значения. Прием сообщения еще не окончен, но его обработка уже завершена...
P.S. Конечно, этот алгоритм не отменяет необходимость обработки таймаутов.
Пробовал, но программа получается дико несмотрибельной. При достаточном количестве команд, появлеются дикие деревья вложенных IF, Количество внеших IF стремится к размеру алфавита, а внутренних при одинаковых первых символах, также прибаляет новые внутренние ветки.
В итоге скорость не на много повышается, а писать не удобно. Единственное, что я сделал для ускорения, это считаю длину полученной посылки во время приёма. Процесс сравнивания сначала пытается найти похожий шаблона ответа в ответах фиксированной длины (OK, ERROR, CONNECT ...), если же после попадания в раздел нужной длины соответвий не найдено, то идем в раздел ответов неопределённой длины (+IPD, REMOTE IP: ...). Если и там ответ не найден, то получен не шаблонный ответ, который будет обработан по индивидуальному алгоритму для каждой нестандартной комады.
Мне кажется более гуманно. Даём модему нормально высказаться, потом поднимаем RTS и спокойно обработать полученный ответ.
А в вашем алгоритме получается не намного быстрее, но вы тем самым не даёте модему свободно выражаться. Ведь наверняка, если обработка ответа идёт во время получения, то возможно, что контроллер будет не готов к продолжению приёма к моменту получения нового байта.