реклама на сайте
подробности

 
 
> GSM модем + TNKernel
hound
сообщение Mar 23 2015, 18:39
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 15-02-15
Пользователь №: 85 179



Добрый день. Есть GSM модем, управление, которого производится AT командами.
Общий вид "общения" с модемом:
1. Отправляется команда
2. Ответ модема на команду (может отсутствовать)
3. Строка "OK", что мол команда выполнена.

Соответственно есть команды, которые возвращают значение состояния модема, например:
AT+CREG?

+CREG: 0, 1
OK

А есть, которые просто выдают строчку ОК, что команда принята и все, например:
AT

OK

Собственно и нужно отслеживать каждый ответ модема и разбирать его, сейчас я сделал что-то подобное. Функция отправки простой AT команды модему:

Код
uint8_t modem_check_at(void) {
  uint32_t flag, rc;

  uart3_ex_send_string("AT\r\n");
  
  rc = tn_event_wait(&modem_event, MODEM_SAY_OK, TN_EVENT_WCOND_OR, &flag, 300);
  if (rc != TERR_NO_ERR) {
    dbg_send("AT fail\r\n");
    return ACTION_FAIL;
  }

  dbg_send("AT ok\r\n");
  tn_event_clear(&modem_event, ~(MODEM_SAY_OK));
  return ACTION_OK;
}


А в самом прерывании, если от модема пришла строка содержащее слово ОК, то выставляется флаг MODEM_SAY_OK:
Код
  if (strncmp(modem_buffer, "OK", 2) == 0) {
    tn_event_iset(&modem_event, MODEM_SAY_OK);
    return;
  }


С простыми командами так проходит, но сложность возникает с теми командами, в которых нужно разбирать ответ модема.
Например команда: AT+CREG?
После отправки модему она возвращает строку с определенными параметрами и после уже слово ОК, что команда выполнена.
Поэтому простой проверкой на слово ОК не обойтись, нужно разбирать, то что ответил модем.
Сделал таким образом: все строчки, которые пришли от модема складываются в очередь, которую уже должна обработать функция, которая отправляла данную команду модему, опять же пример:
Код
uint8_t modem_creg(void) {
  uint32_t rc, flag, number_queue;
  
  uart3_ex_send_string("AT+CREG?\r\n");
  
  rc = tn_queue_receive(&queue_modem_buffer, (void**)&number_queue, 300);
  if (rc != TERR_NO_ERR) {
    dbg_send("CREG fail!\r\n");
    return ACTION_FAIL;
  }
  
  dbg_send("Answer CREG - ");
  dbg_send(modem_queue_buffer[number_queue]);
  dbg_send_rn();
}

Да момент такой еще, есть один линейный буфер, в который пишутся приходящие символы в прерывании, в том случае когда эту строчку нужно отправить через очередь, содержимое этого линейного буфера копируется в другой буфер, который представляем из себя "массив буферов" и собственно позицию в этом массиве и передается через очередь.

Но в таком случае в очередь может отправится ЭХО модема и вместо ответа "+CREG: 0,2" в функции увидим "AT+CREG?", как вариант прогонять очередь до тех пор пока не попадется нужный нам ответ:
Код
  do {
    rc = tn_queue_receive_polling(&queue_modem_buffer, (void**)&number_queue);

    if (strncmp(modem_queue_buffer[number_queue], "+CREG", 5) == 0) {
      return number_queue;
    }
  } while (rc == TERR_NO_ERR);


Но это кажется сильно натянутым решением...
Эхо от модема отключать не желательно,хотя это отчасти и решило бы проблему, но опять же не полностью.
И кроме однострочных команд, модем может выдать много строчные команды.

В общем, у кого-нибудь был опыт работы с АТ командами, кто как реализовал? Заранее благодарен за любой совет/пинок в нужную/правильную сторону.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 15:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.01358 секунд с 7
ELECTRONIX ©2004-2016