Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Непонятка с СОМ портом  (Прочитано 15535 раз)
0 Пользователей и 1 Гость смотрят эту тему.
flare
Гость
« : 25-10-2003 17:23 » 

Симптомы следующие: Программа открывает файл СОМ порта, видит, что в нем лежит несколько байт (они там на самом деле лежат), пытается считать и ReadFile возвращает 0 и число прочитанных байт тоже 0. Как такое может получиться?
Кроме того непонятка усиливается еще и тем, что другая программа, более простая, открывает файл СОМ порта с теми же самыми параметрами, также настраивает буферы и таймауты, видит там то же самое количество байт и благополучно получает их.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 25-10-2003 18:17 » 

А ты преведи свой код: от CreateFile() до ReadFile().

Кстати, тема имеет более подходящие разделы: "С/С++ для ОС" и "Windows". Может перенести?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
flare
Гость
« Ответ #2 : 25-10-2003 18:57 » 

На счет переноса - не возражаю
Код выглядит следующим образом:
инициализация порта производится в функции:
BOOL CDesantDev::Initialize(LPCTSTR lpCommPort)
{
   m_hComm=CreateFile(lpCommPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
   if(m_hComm==INVALID_HANDLE_VALUE)
      return FALSE;
   DCB dcb;
   dcb.BaudRate = 115200;
   dcb.ByteSize = 8;
   dcb.DCBlength = sizeof(DCB);
   dcb.Parity = false;
   dcb.fBinary = true;
   dcb.fOutxCtsFlow = false;
   dcb.fOutxDsrFlow = false;
   dcb.fDtrControl = DTR_CONTROL_DISABLE;
   dcb.fDsrSensitivity = false;
   dcb.fTXContinueOnXoff = false;
   dcb.fOutX = false;
   dcb.fInX = false;
   dcb.ErrorChar = false;
   dcb.fNull = false;
   dcb.fRtsControl = RTS_CONTROL_DISABLE;
   dcb.fAbortOnError = false;
   dcb.StopBits = 2;
   COMMTIMEOUTS TimeOuts;
   TimeOuts.ReadIntervalTimeout = 1;
   TimeOuts.ReadTotalTimeoutConstant = 10;
   TimeOuts.ReadTotalTimeoutMultiplier = 1;
   TimeOuts.WriteTotalTimeoutConstant = 3;
   TimeOuts.WriteTotalTimeoutMultiplier = 1;
   SetCommTimeouts(m_hComm,&TimeOuts);
   SetCommState(m_hComm,&dcb);
   SetupComm(m_hComm,0x1000,0x1000);
   SetCommMask(m_hComm,EV_RXCHAR|EV_TXEMPTY|EV_BREAK);
   PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
   return TRUE;
}

Чтение файла порта производится отдельным потоком, его функция выглядит следующим образом:
DWORD FrDsntInput(LPVOID lParam)
{  
   BYTE szBuffer[MAX_PACKAGE_SIZE+48];
   BOOL bResult;
   DWORD dwEvtMask;
   DWORD dwError;
   DWORD dwBytes;
   COMSTAT csStat;
   CTerminalDlg* pWnd=(CTerminalDlg*)lParam;
   ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CTerminalDlg)));
   CEvent& event=pWnd->m_Quit;
   OVERLAPPED o;
   o.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
   HANDLE Handles[]={o.hEvent,event};
   for(;Ага
   {
      ResetEvent(o.hEvent);
      if(!WaitCommEvent(pWnd->m_DesantDev.m_hComm,&dwEvtMask,&o))
      {
         if(WaitForMultipleObjects(2,Handles,FALSE,INFINITE)==WAIT_OBJECT_0+1)break;
      }
      if(dwEvtMask & EV_BREAK)break;
      else if(dwEvtMask & EV_RXCHAR)
      {
         ClearCommError(pWnd->m_DesantDev.m_hComm,&dwError,&csStat);
         ResetEvent(o.hEvent);
         if(!ReadFile(pWnd->m_DesantDev.m_hComm, szBuffer,    csStat.cbInQue, &dwBytes, &o))
         {
            if(WaitForMultipleObjects(2,Handles,FALSE,INFINITE)==WAIT_OBJECT_0+1)break;
         }
         for(UINT i=0;i<csStat.cbInQue;i++)
            pWnd->m_DesantDev.m_InBuffer.WriteChar(szBuffer);
      }
   }
   return 0;
}
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #3 : 25-10-2003 19:05 » 

Цитата

FILE_FLAG_OVERLAPPED,NULL

А чего ты Overlapped флаг поставил, а структуру не заполнил???
Записан

А птичку нашу прошу не обижать!!!
flare
Гость
« Ответ #4 : 25-10-2003 19:13 » 

Думаете, из-за этого возможен такой косяк?
А как тогда объяснить нормальную работу более простой проги, которая открывает порт следующей функцией:
BOOL CModem::Initialize(LPCTSTR lpCommPort)
{
   m_hComm = CreateFile(lpCommPort,
      GENERIC_READ | GENERIC_WRITE, 0, NULL,
      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

   if (m_hComm == INVALID_HANDLE_VALUE)
      return FALSE;

   DCB dcb;

   GetCommState(m_hComm, &dcb);
   BuildCommDCB("baud=19200 parity=N data=8 stop=1", &dcb);
   SetCommState(m_hComm, &dcb);

   SetCommMask(m_hComm, EV_BREAK | EV_RXCHAR);

   return TRUE;
}

 а читает из порта аналогичным потоком:

DWORD InData(LPVOID lParam)
{
   BYTE szBuffer[4096];

   DWORD dwEvtMask;
   DWORD dwError;
   DWORD dwBytes;
   COMSTAT csStat;

   CTerminalDlg *pWnd = (CTerminalDlg *)lParam;
   ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CTerminalDlg)));

   CEvent& event = pWnd->m_Quit;

   OVERLAPPED o;
   o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

   HANDLE Handles[] = { o.hEvent, event };

   for (; Ага
   {
      ResetEvent(o.hEvent);

      if (!WaitCommEvent(pWnd->m_Modem.m_hComm, &dwEvtMask, &o))
      {
         if (WaitForMultipleObjects(2, Handles, FALSE, INFINITE) ==
            WAIT_OBJECT_0+1)
            break;
      }

      if (dwEvtMask & EV_BREAK)
         break;
      else if (dwEvtMask & EV_RXCHAR)
      {
         ClearCommError(pWnd->m_Modem.m_hComm,   &dwError, &csStat);

         ResetEvent(o.hEvent);

         if (!ReadFile(pWnd->m_Modem.m_hComm, szBuffer,
            csStat.cbInQue, &dwBytes, &o))
         {
            if (WaitForMultipleObjects(2, Handles, FALSE, INFINITE) ==
               WAIT_OBJECT_0+1)
               break;
         }
      
         for (UINT i = 0; i < csStat.cbInQue; i++)
            pWnd->m_Modem.m_InBuffer.WriteChar(szBuffer);
      }
   }

   return 0;
}
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #5 : 25-10-2003 19:20 » 

Не вижу разницы принципиальной в коде.
Дедуктивно можем предположить, что разница в другом.
У меня была ситуевина, когда программка сама по себе иногда вываливалась крича о неправльных обращениях куда то и т.д.
Поиски не приводили к успеху, но выяснилось все очень просто, в омент когда было обращение к файлу, я не отслеживал правильность и наличие возможности к чтению, заполнял массив, потом его использовал исходя из размера файла..
Если я файл не просматривал и не занимал - все читалось на ура.
А стоило занять файл массив оказывался пустой, а он наращивался динамически.

А все все free и т.д. были..
Ну это лирика.
Я не знаю почему у тебя не читает - но мне непонятно зачем ставить флаг распределенного доступа не отдавая структуру этого доступа. Если не нужен он, то ставь 0 и все, если нужно что бы свободно и читать и писать в порт с разных потоков и программ, то пиши и структуру - иначе работать не будет...
Записан

А птичку нашу прошу не обижать!!!
flare
Гость
« Ответ #6 : 25-10-2003 19:26 » 

Ладно, спасибо, вроде понял. Если что - спрошу еще.
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #7 : 25-10-2003 20:49 » 

Сначала напиши 100% работающий код - тем тут с ним вполне пного - юзай поиск, а когда рабочий код не будет работать - смотри железо - мож просто контроллер улетел тьфу тьфу - что б не сглазить... Ага
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 27-10-2003 07:27 » 

Цитата

На счет переноса - не возражаю
Код выглядит следующим образом:
инициализация порта производится в функции:
BOOL CDesantDev::Initialize(LPCTSTR lpCommPort)
{
m_hComm=CreateFile(lpCommPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(m_hComm==INVALID_HANDLE_VALUE)
return FALSE;


поставь вместо FILE_FLAG_OVERLAPPED  "NULL"
просто попробуй - у меня та же беда была - Джон просветил Улыбаюсь
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 27-10-2003 08:58 » 

Цитата: flare
Думаете, из-за этого возможен такой косяк?


Возможен, ReadFile пытается считать инфу из порта, но по какой-то причине не делает этого, тогда она не ждёт, как в синхронной  случае (OVERLAPED флаг не поставлен), а выпрыгивает с ошибкой ERROR_IO_PENDING. Тогда считанную инфу можно получить в поле этой структуры (ща не помню). И по необходимости продолжить или прекратить IO.

А тему однозначно надо перенести.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
flare
Гость
« Ответ #10 : 29-10-2003 08:46 » new

Заработало, всем спасибо.
Я оставил FLAG_OVERLAPPED но при инициализации порта добавил две структуры OVERLAPPED (для чтения и записи) и проинициализировал их функциями memset();

Правда теперь новый глюк: с СОМ2 портом программа работает нормально, а с СОМ1 - через раз и реже. Ошибка в том, что считывается (из СОМ1) не то, что туда было записано. и даже не то количество байт. Может есть какие-нибудь особенности, которые влияют на работу СОМ1?
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines