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

Парсер ответов модема SIM900r

Написал я парсер на ответ модема WaitOK(const char *S) . Работает исправно, но представляется мне кривым.

Во - первых это отдельная функция, где по таймеру ожидается ответ модема и основной поток не выполняется. Во - вторых получилось громоздко.

 

int WaitOK(const char *S) {//Ожидание символа (*S) от модема
    timer1.timerId=1;//таймера 
    int j;//Для копирования буфера
    s8 *i=0;//Для strstr
    int C = 5;//Ждем 5*3с
    while (C){//Выполняется пока Сikl <> 0
        eat1_02GetEvent(&flEventBuffer);//Проверка событий
            switch(flEventBuffer.eventTyp) {//
                case EVENT_TIMER://Событие - прерывание от таймера
                    if (flEventBuffer.eventData.timer_evt.timer_id == 1)//Если индекс таймера 1:
                        {ebdat8_01StartTimer(timer1); if (C) {C--;}
                        }//if (flEventBuffer.eventData.timer_evt.timer_id == 1)
                    break;                                        //case EVENT_TIMER:
                case EVENT_MODEMDATA://
                    if(flEventBuffer.eventData.modemdata_evt.type == MODEM_CMD){//Если есть ответ от модема
//Поиск символа в строке
                        i=(s8*)strstr((const char *)flEventBuffer.eventData.modemdata_evt.data,S);
                        if(i){C = 0;}//Если ответ есть - ВЫХОД
//Нижние три строчки кода должны быть именно здесь, поскольку в буфер складывается все до прихода строки *S Нужно для декодирования
                    for (j = 0; j < flEventBuffer.eventData.modemdata_evt.length; j++)//копирование буфера
                               {RecieveBuf[RecieveBufIndex]=flEventBuffer.eventData.modemdata_evt.data[j];//модема
                               if (RecieveBufIndex<250) {RecieveBufIndex++;}}
                }//if(flEventBuffer.eventData.modemdata_evt.type == MODEM_CMD)
                    break;//EVENT_MODEMDATA:
               default:
                   break;
            }//switch(flEventBuffer.eventTyp)
    }//while (C)
    if (!i) {ErrLog("WaitOKNR\n",9);}
    return (int)(i);
}

 

Написал я другой парсер с кольцевым буфером. В ветке case EVENT_MODEMDATA я заполняю кольцевой буфер, оъявленный глобально:

char ModemRBUF[256]; //Кольцевой буфер приема ответов модема
int ModemRBUFTail=0; //Хвост кольцевого буфера модема
int ModemRBUFHead=0;  //Голова кольцевого буфера модема

 

{if(flEventBuffer.eventData.modemdata_evt.type == MODEM_CMD)//Если принят ответ
            {int i;//
            int length = flEventBuffer.eventData.modemdata_evt.length;//Длина принятой строки
            char *string = (char *)flEventBuffer.eventData.modemdata_evt.data;//Данные в string
            for (i=0; i<length;    i++) {//Копирование содержимого
                ModemRBUFTail = (ModemRBUFTail + 1)&255;//принятого буфера в 
                ModemRBUF[ModemRBUFTail] = string[i];}//кольцевой буфер. Вставить memcpy!!!
            ebdat9_02SendToSerialPort(string, length);}//Вывод в порт 0

 

 

В основном потоке функцией if(read_line(ModemLBUF)) я проверяю наличие информации в кольцевом буфере и перекладываю если есть в линейный:

 

    while (TRUE){//Прием команд. printf("\n%s\n", buf); - Эхо
char *read_line(char buf[]);    //Чтение в линейный буфер принятых символов
//Анализ приема строки от модема
    if(read_line(ModemLBUF)) //read_line( buf ) читает в buf принятые символы
        {parseCmd(ModemLBUF);}//Разбор принятой строки если read_line( buf ) <> 0

 

Если функция read_line( buf ) обнаруживает символы \n или \r в потоке, вызывается функция void parseCmd(char *cmd);

 

char *read_line(char buf[])//
{    static  int     cnt = 0; //Индекс приёмного буфера
    char c; //Принимаемый символ
    if(ModemRBUFTail == ModemRBUFHead) //Если нет принятых символов
    {return  (char *) 0;} //Возвратить нуль
    ModemRBUFTail = (ModemRBUFTail + 1) & 255;    //Перемещение по кольцевому буферу
    c = ModemRBUF[ModemRBUFTail]; //Читать символ
    if(c == '\n' || c == '\r') //Если принято 0xD или 0xA:
    {    buf[cnt] = 0; //записываем ноль в конец принятой строки в буфере
        cnt = 0; //Обнуляем счётчик
        return  buf;} //Возвращаем указатель на буфер
    else //Если не принято 0xD или 0xA:
    {    if(cnt < 199) //80 - длина строки CONFIG_CONSOLE_LINE_SIZE. Если индекс буфера не вышел за предел
        {buf[cnt++] = c;} //записать принятый символ в буфер.
        return  (char *) 0;} //
}//char *read_line(char buf[])

 

А в функцию parseCmd уже легко добавляется все что нужно:

 

void parseCmd(char *cmd){ //cmd указывает на принятый с консоли буфер
    char *pKey=0; //
    if( cmd == 0 ) {return;} //Если принятая строка 0, выход
    pKey = strstr(cmd,"OK"); //Поиск строки
    if (pKey) {OKFLAG = 1; return;} //ответа ОК
    pKey = strstr(cmd,"ERROR"); //Поиск строки
    if (pKey) {ERRORFlag = 1;  return;} //ответа ERROR
    if (SendSMS==2) {     //Если первая часть СМС уже отправлена
        pKey = strstr(cmd,">"); //Ловим приглашение ввести СМС
        if (pKey) {Skoba = 1;} //Если приглашение обнаружено
         return;}     //
    if (CheckKey) { //Если включена проверка ключей
        pKey = strstr(cmd, "FtvgQ6mELE5G6nQJSVxO7icAmfip7");//Поиск в линейном буфере
        if (pKey) {KEY1 = 1; CheckKey = 0;  return;} //KEY1 = 1 - отправка СМС
        pKey = strstr(cmd, "AhY3K7E65L987NT6Z98w53sdr39"); //Поиск в линейном буфере
        if (pKey) {KEY2 = 1; CheckKey = 0;  return;} //KEY2 = 1 - Дозвон
        pKey = strstr(cmd, "LQN45rMFR"); //Поиск в линейном буфере
        if (pKey) {KEY3 = 1; CheckKey = 0;  return;} //KEY3 = 1 - снятие с охраны
    }//if (CheckKey)

 

Преимущество такого метода - гибкость и отсутствие зацикливания. Если кто расскажет про недостатки - буду благодарен.

Прямо беда с этими комментариями. Никак ровно не получается.

Изменено пользователем Димон Безпарольный

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


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

Преимущество такого метода - гибкость и отсутствие зацикливания.

 

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

Хотя, дело вкуса :laughing:

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


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

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

Хотя, дело вкуса :laughing:

Отчего же. Я недавно написал обработчик для SAM7s256 на прием / передачу с кольцевыми буферами. Не так уж сложно. Но это SimCom, а не просто процессор. Просветите, как написать под прерывание если в нем уже вертится своя ОС??

Изменено пользователем Димон Безпарольный

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


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

Отчего же. Я недавно написал обработчик для SAM7s256 на прием / передачу с кольцевыми буферами. Не так уж сложно. Но это SimCom, а не просто процессор. Просветите, как написать под прерывание если в нем уже вертится своя ОС??

 

Ясно, я просто думал, что прога для МК пишется, теперь все понятно :biggrin: Это вопрос скорее к CADiLO...

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

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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