Димон Безпарольный 2 7 октября, 2014 Опубликовано 7 октября, 2014 (изменено) · Жалоба Написал я парсер на ответ модема 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) Преимущество такого метода - гибкость и отсутствие зацикливания. Если кто расскажет про недостатки - буду благодарен. Прямо беда с этими комментариями. Никак ровно не получается. Изменено 7 октября, 2014 пользователем Димон Безпарольный Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 53 7 октября, 2014 Опубликовано 7 октября, 2014 · Жалоба Преимущество такого метода - гибкость и отсутствие зацикливания. Вы принципиально не пишете обработчики уартов на прерываниях?? Сколь писал для модемов - на прерываниях куда удобнее, в основной программе в это время выполняются другие действия, и не надо ждять ответов относительно тормозного модема. Удобно программировать, даже без всяких РТОСов. Хотя, дело вкуса :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Димон Безпарольный 2 7 октября, 2014 Опубликовано 7 октября, 2014 (изменено) · Жалоба Вы принципиально не пишете обработчики уартов на прерываниях?? Сколь писал для модемов - на прерываниях куда удобнее, в основной программе в это время выполняются другие действия, и не надо ждять ответов относительно тормозного модема. Удобно программировать, даже без всяких РТОСов. Хотя, дело вкуса :laughing: Отчего же. Я недавно написал обработчик для SAM7s256 на прием / передачу с кольцевыми буферами. Не так уж сложно. Но это SimCom, а не просто процессор. Просветите, как написать под прерывание если в нем уже вертится своя ОС?? Изменено 7 октября, 2014 пользователем Димон Безпарольный Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 53 7 октября, 2014 Опубликовано 7 октября, 2014 (изменено) · Жалоба Отчего же. Я недавно написал обработчик для SAM7s256 на прием / передачу с кольцевыми буферами. Не так уж сложно. Но это SimCom, а не просто процессор. Просветите, как написать под прерывание если в нем уже вертится своя ОС?? Ясно, я просто думал, что прога для МК пишется, теперь все понятно Это вопрос скорее к CADiLO... Изменено 7 октября, 2014 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться