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

 
 
 
Reply to this topicStart new topic
> Парсер ответов модема SIM900r, Покритикуйте пожалуйста.
Димон Безпарольн...
сообщение Oct 7 2014, 00:40
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Написал я парсер на ответ модема 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)


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

Сообщение отредактировал Димон Безпарольный - Oct 7 2014, 15:10
Go to the top of the page
 
+Quote Post
mantech
сообщение Oct 7 2014, 09:39
Сообщение #2


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(Димон Безпарольный @ Oct 7 2014, 03:40) *
Преимущество такого метода - гибкость и отсутствие зацикливания.


Вы принципиально не пишете обработчики уартов на прерываниях?? Сколь писал для модемов - на прерываниях куда удобнее, в основной программе в это время выполняются другие действия, и не надо ждять ответов относительно тормозного модема. Удобно программировать, даже без всяких РТОСов.
Хотя, дело вкуса laughing.gif
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Oct 7 2014, 13:47
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(mantech @ Oct 7 2014, 13:39) *
Вы принципиально не пишете обработчики уартов на прерываниях?? Сколь писал для модемов - на прерываниях куда удобнее, в основной программе в это время выполняются другие действия, и не надо ждять ответов относительно тормозного модема. Удобно программировать, даже без всяких РТОСов.
Хотя, дело вкуса laughing.gif

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

Сообщение отредактировал Димон Безпарольный - Oct 7 2014, 15:11
Go to the top of the page
 
+Quote Post
mantech
сообщение Oct 7 2014, 15:52
Сообщение #4


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(Димон Безпарольный @ Oct 7 2014, 16:47) *
Отчего же. Я недавно написал обработчик для SAM7s256 на прием / передачу с кольцевыми буферами. Не так уж сложно. Но это SimCom, а не просто процессор. Просветите, как написать под прерывание если в нем уже вертится своя ОС??


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

Сообщение отредактировал mantech - Oct 7 2014, 15:53
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 17th August 2025 - 20:08
Рейтинг@Mail.ru


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