Jump to content

    
Sign in to follow this  
M@@}{

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

Recommended Posts

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

Ковыряю модем - 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;
    }
  }
}

 

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

Edited by hound

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this