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

SIM900. Прием команд от TCP сервера.

Самое первое правило - обрабатывать ВСЕ!!! последовательности от модема.

 

Второе - последовательность AT команд четко регламетирована (см GSM 07.07 раздел 4).

Заметьте, у всех команд стандарта есть final result code (чего не скажешь творчестве собственных расширений производителей модемов)

Все что между - результат выполения команды.

 

И еще есть ансинхронные ответы. Могут влезть куда угодно. либо пропускайте их, либо применяйте. НО РАСПОЗНАТЬ их надо!!

Однозначно! Все прочее (кроме автомата) - просто мертвому припарки. Выкрутиться не получится.

Кстати, у оператора case в любом "языковом исполнении" всегда имеется свой else, позволяющий пропустить что-угодно как с распознаванием, так и без, если со стороны пришел некий "невнятный" и не вписывающийся в рамки протокола ответ - команда вместо данных и в таком духе.

 

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


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

Тоже сначала делал обработку по таймауту.

Все было очень плохо.

 

Потом перешел на обработку по концу строки.

По приходу строки выставляю сигнал ртс, в основном цикле обрабатываю строку, убираю ртс когда процессор готов к приему.

Имею проблему только с командой чтения имея, т.к. имей возвращается во второй строке и без заголовка.

В этом случае обрабатываю второую строку и проверяю что-бы ее длинна была 14 символов.

При этом эхо включено, и оно не мешает процессору вылавливать необходимые ответы.

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


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

Однозначно! Все прочее (кроме автомата) - просто мертвому припарки. Выкрутиться не получится.

Кстати, у оператора case в любом "языковом исполнении" всегда имеется свой else, позволяющий пропустить что-угодно как с распознаванием, так и без, если со стороны пришел некий "невнятный" и не вписывающийся в рамки протокола ответ - команда вместо данных и в таком духе.

Немного не понял про else. Что Вы имеете ввиду?

 

Тоже сначала делал обработку по таймауту.

Все было очень плохо.

 

Потом перешел на обработку по концу строки.

По приходу строки выставляю сигнал ртс, в основном цикле обрабатываю строку, убираю ртс когда процессор готов к приему.

Имею проблему только с командой чтения имея, т.к. имей возвращается во второй строке и без заголовка.

В этом случае обрабатываю второую строку и проверяю что-бы ее длинна была 14 символов.

При этом эхо включено, и оно не мешает процессору вылавливать необходимые ответы.

Кстати, вот что хотел спросить. Если мы выставляем ртс, и за это время в буфере SIM900 накопится, например, три сообщения, то, когда мы отпустим ртс, они вывалятся все разом, без пауз между ними?

 

Самое первое правило - обрабатывать ВСЕ!!! последовательности от модема.

 

Второе - последовательность AT команд четко регламетирована (см GSM 07.07 раздел 4).

Заметьте, у всех команд стандарта есть final result code (чего не скажешь творчестве собственных расширений производителей модемов)

Все что между - результат выполения команды.

 

И еще есть ансинхронные ответы. Могут влезть куда угодно. либо пропускайте их, либо применяйте. НО РАСПОЗНАТЬ их надо!!

Я всё понимаю, и стараюсь учесть все возможные ответы от модема. Но если пытаться определять конец посылки по CR/LF, учитывая то, что CR/LF может быть несколько, например \r\nOK\r\nблаблабла\r\n, то нам как минимум нужно знать, сколько \r\n будет в ответе от модема. Посчитать их, конечно, легко, но если асинхронное сообщение появилось, с ним как быть? Направьте меня в нужную сторону. Вообще, конечно, то, что форматы ответов так разнятся от команды к команде, сильно осложняет их обработку и даже немного раздражает.

 

Что до меня, то пока особых трудностей с определением конца посылки по таймауту не возникало. Работает достаточно надежно. Кстати, снизил длительность таймаута до 1мс., пока полет нормальный.

 

Кстати, по поводу собственно сабжа. У меня трудности, описанные в первом посте этой темы возникали в основном из-за ошибки переполнения буфера UART, связанной с отключением прерываний в другом, параллельном процессе. Так что проблема, можно сказать, почти решена. Сейчас тестирую прозрачный режим, обсуждение в соседней теме . Буду рад выслушать Ваши мнения.

 

Это как раз не страшно. У меня идет работа с голосом (прием звонка, дозвон), SMS (прием и отправка) и GPRS (клиент) , плюс полный набор обслуживающих команд и всего в сумме получается не более 60 вариантов заголовков команд/ответов. Если делать не побуквенное сравнение, а более оптимизированный парсер, то получается быстрое автоматическое определение что пришло. Но с GPRS, да, в непрозрачном режиме приходится выкручиваться, а в прозрачном нет мультисокетов. Как вариант - реализовать режим мультиплексирования (CMUX).

Было бы очень удобно, если бы китайцы добавили аналог +CIPRXGET, но не по незапрашиваемому ответу, а по запросу.

Мне как раз мультисокет и не нужен, мне достаточно одного соединения. Значит ли это, что мне лучше воспользоваться прозрачным режимом?

И второе. Намекните, если можно, про устройство Вашего оптимизированного парсера. Как он работает?

 

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


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

После снятия ртса сим выдаст следующую строку, проц выставит ртс, обработает ее, уберет ртс и так до тех пор, пока сим все строки не выдаст.

 

Большинство сообщений от сима имею заголовок, +IPR например. В програме заданы все заголовки на которые надо реагировать.

Если в пришедшей строке найден один из заголовков, то проц уходит в его обработчик, который знает в какой что читать.

ОК и ЕРРОР так-же определены как заголовки. При их приходе проверяется проверяется последняя переданная команда (храню условный номер).

Если на эту команду ответ должен быть ОК, а пришел ЕРРОР, то снова передаю ту команду.

Если пришел ОК то переход к слудующей команде. Это уже обычная машина сосостояний.

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


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

Добавлю еще, что большинство ответов можно расматривать как заголовок и набор параметров, разделенных запятыми. параметры могут быть int, hex, str

в большинстве случаев достаточно распознавать не более 4-х параметров.

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


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

Если пришел ОК то переход к слудующей команде. Это уже обычная машина сосостояний.

Не-а. Надо сначала "пропихнуть" автомат в следующее состояние, которое будет ждать прихода именно Ок.

Немного не понял про else. Что Вы имеете ввиду?

Вот - http://www.delphisources.ru/forum/showthread.php?t=6547 Обратите внимание, что case намного прозрачнее if. Но это его удобство, проще читать код, все видно хорошо.

А ссылку на статью давал, там есть рисунки с кодами автомата. Для возвртата в исходное состояние используется оператор goto. И под каждым case устанавливается следующее состояние.

Короче, все просто оказалось, но намучился с этим всем конкретно, когда шел не автоматным путем.

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


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

Я всё понимаю, и стараюсь учесть все возможные ответы от модема. Но если пытаться определять конец посылки по CR/LF, учитывая то, что CR/LF может быть несколько, например \r\nOK\r\nблаблабла\r\n, то нам как минимум нужно знать, сколько \r\n будет в ответе от модема. Посчитать их, конечно, легко, но если асинхронное сообщение появилось, с ним как быть? Направьте меня в нужную сторону. Вообще, конечно, то, что форматы ответов так разнятся от команды к команде, сильно осложняет их обработку и даже немного раздражает.

 

Что до меня, то пока особых трудностей с определением конца посылки по таймауту не возникало. Работает достаточно надежно. Кстати, снизил длительность таймаута до 1мс., пока полет нормальный.

Тоже определял конец строки по таймауту. Работало.

Потом перешел по \r\n. По \r\n оказалось более работоспособно, и нет никакой необходимости в знании сколько их будет в ответе. К примеру посмотрим на строку \r\nOK\r\nблаблабла\r\n, по первому \n мы видим что это начало строки (так как количество принятых байтов равно 2). По второму получаем ответ OK. По третьему получаем ответ блаблабла. Поэтому при разборе ответов, задача сводится к проверке "наборов байтов находящихся между \r\n". Единственное что портит всю картину это приглашение к вводу данных "> ", но и это обходится очень просто.

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

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


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

Лексема (Lexical) token Lexical unit - Языковая конструкция, по соглашению представляющая элементарную синтаксическую единицу [из п. 2 Табл. 1 ГОСТ 28397-89] :)

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


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

...Единственное что портит всю картину это приглашение к вводу данных "> "...

 

Жду 1 сек, и подразумеваю, что пришло приглашение. Не видел ситуации, когда бы приглашение не пришло при отправке смса.

А при передаче данных, мне мой сервер подтверждает получение посылки.

 

Немного сложно обрабатывать ответы, которые не содержат заголовка (чтение имей).

 

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


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

Жду 1 сек, и подразумеваю, что пришло приглашение. Не видел ситуации, когда бы приглашение не пришло при отправке смса.

А при передаче данных, мне мой сервер подтверждает получение посылки.

 

Немного сложно обрабатывать ответы, которые не содержат заголовка (чтение имей).

Аж целую секунду, я не могу позволить себе столько ждать.

В случае с \r\n никаких сложностей.

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


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

Блокируется только машина юарта, она переходит в состояние ожидания, а все остальные машины продолжают работать.

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


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

Единственное что портит всю картину это приглашение к вводу данных "> ", но и это обходится очень просто.

А как обходите, просто конечный автомат парсера настраиваете на поиск ">" без обрамления \r\n?

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


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

Я думаю.

В прерывании прихода символа из юарта, проверяем, если автомат находится в режиме ожидания приглашения, и пришел символ приглашения, то переходим к следующему состоянию (отправка текста смса, отправка сообщения серверу).

Параллельно тикает таймер, если таймер истек, значит приглашение не пришло, снова пробуем.

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


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

В прерывании прихода символа из юарта, проверяем, если автомат находится в режиме ожидания приглашения, и пришел символ приглашения, то переходим к следующему состоянию (отправка текста смса, отправка сообщения серверу).

У Вас автомат общий - и на отправку и на прием? По крайней мере так понял из сообщения.

Мне удобнее иметь отдельный конечный автомат на прием, который периодически запускается и которому можно указать, какой токен в данный момент ожидается. Да и в прерывании уарта лучше просто заполнять кольцевой буфер. Всё imho. =)

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


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

Юарт у это разделяемый ресурс. Доступом к нему управляет структура из двух полей, первое это режим работы юарта, второе время в этом режиме.

Разным независимым задачам необходим доступ к юарту (0-свободен, 1-залочен (поломан), 2-конфигурация сима, 3-чтение температуры, 4-чтение уровня сигнала, 5-чтение регистрации, 6-подключение с серверу, 7-передача данных ...).

Все эти задачи это независымые автоматы.

 

Если в режиме юарта записан 0, значит юарт свободен и любая задача (автомат) может его занять (записать в режим свой номер) и запустить таймер освобождения юарта (на случай если задачу заглючит).

 

Если, допустим, доступ получила задача подключения к серверу, она должна отправить несколько команд. Отослала первую, пришел ок, общий обработчик окея видит, что работает задача подключения,

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

Он (автомат подключения) переходит в следующее состояние, шлет следующую команду, либо начинает сначала, либо завершает работу...

 

Все автоматы завязаны на один хардверный таймер, в тике которго проверяются таймера всех автоматов, если какой-то таймер дотикал до 0, то этот автомт переводится в следующее состояние.

В общем, все автоматы переходят в новое состояние либо по получению ответа, либо по обнулению таймера.

 

Надеюсь из этого можно что-то понять :)

 

 

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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