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

Общий вопрос приема данных

Откопал же тему)) надеюсь тут еще кто-то есть и увидит мое сообщение)

Ковыряю модем - Quectel m66, но особой роли не играет, главное те же самые АТ команды.

Использую операционку TNKernel, но тоже особой роли не играет, разве что в этой системе в очереди передается указатель на данные, а не сами данные как, например, во FreeRTOS. К этому чуть позже вернемся)

 

1. Сделал отдельный таск под работу с модемом.

2. Линейный буфер, куда складываются все приходящие данные с модема, которые потом из прерывания передаются в функцию обработчик (modem_process_buffer).

В функции обработчике (modem_process_buffer) проверяется строка от модема со следующими условиями:

если пришел ответ 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;
}

 

Тут все просто, нужно только дождаться чтобы флаг ОК был выставлен. Сложности начинаются с командами в которых нужно парсить ответ от модема.

Например, команда AT+CREG?

На нее модем отвечает следующим образом:

+CREG: 0, 1

OK

 

Нужно дождаться именно этого ответа. Сделал следующим образом:

Перед отправкой команды помещаю в некоторые переменные условия по которым мы должны отправлять очередь:

uint8_t modem_creg(void) {
  uint32_t rc, flag, number_queue;
  
  // Используется в прерывании для определения условия отправки очереди
  strcpy(wait_data, "+CREG");
  wait_length = 5;
  uart3_ex_send_string("AT+CREG?\r\n");
  
  // Ждем ответ ОК от модема, если ОК пришло значит команда успешно выполнена
  rc = tn_event_wait(&modem_event, MODEM_SAY_OK, TN_EVENT_WCOND_OR, &flag, 300);
  if (rc != TERR_NO_ERR) {
    dbg_send("CREG fail\r\n");
    return ACTION_FAIL;
  }
  
  tn_event_clear(&modem_event, ~(MODEM_SAY_OK));
  
  // В очереди получаем порядковый номер в массиве для нашего сообщения
  tn_queue_receive_polling(&queue_modem_buffer, (void**)&number_queue);
  
  dbg_send("Answer CREG - ");
  dbg_send(modem_queue_buffer[number_queue]);
  dbg_send_rn();
  
  return ACTION_OK;
}

 

И в свою очередь в функции modem_process_buffer (в прерывании):

  if (strncmp(modem_line_buffer, wait_data, wait_length) == 0) {
    modem_send_queue();
  }

 

Либо отправлять в очередь все что пришло и потом уже в функции отправки команды перебирать очереди пока не нашли нужный нам ответ, но так кажется более затратно...

 

И стоит ли в подобных командах CREG, где нужно разбирать ответ от модема дожидаться именно приходящего ОК сообщения? Или можно просто дождаться уже ответа от модема +CREG и его разбирать, а после флаг ОК просто сбросить...

 

Ах да, и вот сам таск для модема:

void modem_queue_func(void *par) {
  dbg_send("Task modem start\r\n");
  
  while (1) {
    modem_reset();
    
    if (modem_check_at()        == ACTION_FAIL) continue;
    if (modem_qimux()           == ACTION_FAIL) continue;
    
    while (1) {
      if (modem_check_at()      == ACTION_FAIL) break;
      if (modem_qistate()       == ACTION_FAIL) break;
      if (modem_cgatt()         == ACTION_FAIL) break;
      if (modem_creg()          == ACTION_FAIL) break;
    }
  }
}

 

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

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

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


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

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

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

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

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

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

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

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

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

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