Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.02.2015, 14:53   #1
Ваниль
Новичок
Джуниор
 
Регистрация: 10.02.2015
Сообщений: 2
По умолчанию Com порт. Бесконечное SERIAL_WAIT_ON_MASK

Доброго времени суток!
Имеется программа, управляющая прибором.
Имеется проблема: если прибор имеет не первый порядковый номер среди всех com-устройств, то соединение не устанавливается. Вот выдержки из portmon:

Когда устройство первое по порядку.

Цитата:
0.05055706 magaz.exe IRP_MJ_CREATE VCP9 SUCCESS Options: Open
0.00000219 magaz.exe IOCTL_SERIAL_GET_BAUD_RATE VCP9 SUCCESS
0.00000062 magaz.exe IOCTL_SERIAL_GET_LINE_CONTROL VCP9 SUCCESS
0.00000050 magaz.exe IOCTL_SERIAL_GET_CHARS VCP9 SUCCESS
0.00000060 magaz.exe IOCTL_SERIAL_GET_HANDFLOW VCP9 SUCCESS
0.00000056 magaz.exe IOCTL_SERIAL_GET_BAUD_RATE VCP9 SUCCESS
0.00000055 magaz.exe IOCTL_SERIAL_GET_LINE_CONTROL VCP9 SUCCESS
0.00000048 magaz.exe IOCTL_SERIAL_GET_CHARS VCP9 SUCCESS
0.00000048 magaz.exe IOCTL_SERIAL_GET_HANDFLOW VCP9 SUCCESS
0.00288578 magaz.exe IOCTL_SERIAL_SET_BAUD_RATE VCP9 SUCCESS Rate: 9600
0.00298659 magaz.exe IOCTL_SERIAL_CLR_RTS VCP9 SUCCESS
0.00298674 magaz.exe IOCTL_SERIAL_CLR_DTR VCP9 SUCCESS
0.00299667 magaz.exe IOCTL_SERIAL_SET_LINE_CONTROL VCP9 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
0.00000075 magaz.exe IOCTL_SERIAL_SET_CHAR VCP9 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
0.00296279 magaz.exe IOCTL_SERIAL_SET_HANDFLOW VCP9 SUCCESS Shake:0 Replace:0 XonLimit:2048 XoffLimit:512
0.00000062 magaz.exe IOCTL_SERIAL_SET_TIMEOUTS VCP9 SUCCESS RI:0 RM:500 RC:5000 WM:1 WC:1
0.00000055 magaz.exe IOCTL_SERIAL_SET_QUEUE_SIZE VCP9 SUCCESS InSize: 2000 OutSize: 2000
0.00000182 magaz.exe IOCTL_SERIAL_PURGE VCP9 SUCCESS Purge: RXCLEAR
0.00226220 magaz.exe IOCTL_SERIAL_SET_WAIT_MASK VCP9 SUCCESS Mask: RXCHAR

0.01099519 magaz.exe IOCTL_SERIAL_WAIT_ON_MASK VCP9 SUCCESS

0.00000102 magaz.exe IOCTL_SERIAL_PURGE VCP9 SUCCESS Purge: TXCLEAR
0.00050729 magaz.exe IRP_MJ_WRITE VCP9 SUCCESS Length 2: N1
Когда устройство не первое.

Цитата:
0.04455936 magaz.exe IRP_MJ_CREATE VCP9 SUCCESS Options: Open
0.00000171 magaz.exe IOCTL_SERIAL_GET_BAUD_RATE VCP9 SUCCESS
0.00000066 magaz.exe IOCTL_SERIAL_GET_LINE_CONTROL VCP9 SUCCESS
0.00000050 magaz.exe IOCTL_SERIAL_GET_CHARS VCP9 SUCCESS
0.00000065 magaz.exe IOCTL_SERIAL_GET_HANDFLOW VCP9 SUCCESS
0.00000055 magaz.exe IOCTL_SERIAL_GET_BAUD_RATE VCP9 SUCCESS
0.00000054 magaz.exe IOCTL_SERIAL_GET_LINE_CONTROL VCP9 SUCCESS
0.00000047 magaz.exe IOCTL_SERIAL_GET_CHARS VCP9 SUCCESS
0.00000048 magaz.exe IOCTL_SERIAL_GET_HANDFLOW VCP9 SUCCESS
0.00288861 magaz.exe IOCTL_SERIAL_SET_BAUD_RATE VCP9 SUCCESS Rate: 9600
0.00299983 magaz.exe IOCTL_SERIAL_CLR_RTS VCP9 SUCCESS
0.00298254 magaz.exe IOCTL_SERIAL_CLR_DTR VCP9 SUCCESS
0.00298428 magaz.exe IOCTL_SERIAL_SET_LINE_CONTROL VCP9 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
0.00000072 magaz.exe IOCTL_SERIAL_SET_CHAR VCP9 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
0.00297880 magaz.exe IOCTL_SERIAL_SET_HANDFLOW VCP9 SUCCESS Shake:0 Replace:0 XonLimit:2048 XoffLimit:512
0.00000062 magaz.exe IOCTL_SERIAL_SET_TIMEOUTS VCP9 SUCCESS RI:0 RM:500 RC:5000 WM:1 WC:1
0.00000058 magaz.exe IOCTL_SERIAL_SET_QUEUE_SIZE VCP9 SUCCESS InSize: 2000 OutSize: 2000
0.00000183 magaz.exe IOCTL_SERIAL_PURGE VCP9 SUCCESS Purge: RXCLEAR
0.00230124 magaz.exe IOCTL_SERIAL_SET_WAIT_MASK VCP9 SUCCESS Mask: RXCHAR

0.90608073 magaz.exe IOCTL_SERIAL_WAIT_ON_MASK VCP9 CANCELLED

0.00000093 magaz.exe IOCTL_SERIAL_PURGE VCP9 SUCCESS Purge: TXCLEAR
0.00000059 magaz.exe IRP_MJ_WRITE VCP9 SUCCESS Length 0:
0.00001337 magaz.exe IRP_MJ_CLEANUP VCP9 SUCCESS
0.12493270 magaz.exe IRP_MJ_CLOSE VCP9 SUCCESS
Во втором случае событие может ожидаться бесконечно. Опыта работы с ком-портами практически нет, не понимаю, в чём дело )-:
Ваниль вне форума Ответить с цитированием
Старый 10.02.2015, 14:53   #2
Ваниль
Новичок
Джуниор
 
Регистрация: 10.02.2015
Сообщений: 2
По умолчанию

Код открытия порта и обмена сообщениями:
Код:
void OpenPort(String portname)
{
     DCB dcb;
     COMMTIMEOUTS timeouts;
 
    COMport = CreateFile(portname.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
 
    if(COMport == INVALID_HANDLE_VALUE)            //если ошибка открытия порта
    {
        int errcode = GetLastError();
       if ((errcode != 2) && (errcode != 5))
           Form1->Info->Lines->Add("Ошибка. Код ошибки: " + IntToStr(errcode));
       return;
    }
 
     dcb.DCBlength = sizeof(DCB);
 
     if(!GetCommState(COMport, &dcb))
      {
       ClosePort();
       MessageDlg((const UnicodeString)"Ошибка соединения: не удалось считать DCB!", mtError, TMsgDlgButtons() << mbOK, 0);
       return;
      }
 
     //инициализация структуры DCB
     dcb.BaudRate = 9600; 
     dcb.fBinary = TRUE;                             
     dcb.fOutxCtsFlow = FALSE;                
     dcb.fOutxDsrFlow = FALSE;              
     dcb.fDtrControl = DTR_CONTROL_DISABLE;     
     dcb.fDsrSensitivity = FALSE;                 
     dcb.fNull = FALSE;                       
     dcb.fRtsControl = RTS_CONTROL_DISABLE;  
     dcb.fAbortOnError = FALSE;         
     dcb.ByteSize = 8;                 
     dcb.Parity = 0;                           
     dcb.StopBits = 0;                                
 
     if(!SetCommState(COMport, &dcb))
      {
       //если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния
       ClosePort();
       MessageDlg((const UnicodeString)"Ошибка соединения: не удалось установить DCB!", mtError, TMsgDlgButtons() << mbOK, 0);
       return;
      }
 
     timeouts.ReadIntervalTimeout = 0;      
     timeouts.ReadTotalTimeoutMultiplier = 500; 
     timeouts.ReadTotalTimeoutConstant = 5000;       
     timeouts.WriteTotalTimeoutMultiplier = 1;   
     timeouts.WriteTotalTimeoutConstant = 1;     
 
     if(!SetCommTimeouts(COMport, &timeouts))
      {
       ClosePort();
       MessageDlg((const UnicodeString)"Ошибка соединения:  не удалось установить тайм-ауты!", mtError, TMsgDlgButtons() << mbOK, 0);
       return;
      }
 
     SetupComm(COMport,2000,2000);
 
     PurgeComm(COMport, PURGE_RXCLEAR);
 
     reader = CreateThread(NULL, 0, ReceiveFromDeviceThread, NULL, 0, NULL);  //создать и запустить поток чтения байтов
     writer = CreateThread(NULL, 0, SendToDeviceThread, NULL, CREATE_SUSPENDED, NULL);  //создаём поток записи в остановленном состоянии (предпоследний параметр = CREATE_SUSPENDED)
}
//------------
DWORD WINAPI SendToDeviceThread(LPVOID)
{
    DWORD temp, signal;
    olwrite.hEvent = CreateEvent(NULL, true, true, NULL);         
    while(1)
    {
        WriteFile(COMport, bufwr, strlen(bufwr), &temp, &olwrite);
         signal = WaitForSingleObject(olwrite.hEvent, INFINITE);    
                                    
        if(!( (signal == WAIT_OBJECT_0) && (GetOverlappedResult(COMport, &olwrite, &temp, true)) ))
            Form1->Info->Lines->Add("Значение не отправлено");
 
        SuspendThread(writer);
    }
}
//-------------
DWORD WINAPI ReceiveFromDeviceThread(LPVOID)
{
    COMSTAT comstat;
    DWORD btr, temp, mask, signal;
     olread.hEvent = CreateEvent(NULL, true, true, NULL);
     SetCommMask(COMport, EV_RXCHAR);
 
     while(true)    
      {
       WaitCommEvent(COMport, &mask, &olread);
 
       signal = WaitForSingleObject(olread.hEvent, INFINITE);
        //если событие произошло
       if(signal == WAIT_OBJECT_0)
        {
         if(GetOverlappedResult(COMport, &olread, &temp, true))
         {
          //если произошло именно событие прихода байта
          if((mask & EV_RXCHAR)!=0)
           {
            ClearCommError(COMport, &temp, &comstat);
            btr = comstat.cbInQue;
            //если действительно есть байты для чтения
            if(btr)
            {
             ReadFile(COMport, bufrd, btr, &temp, &olread);
             ReadBuf(); //вызываем функцию для обработки данных
            }
           }
          }
        }
      }
}
Ваниль вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Бесконечное создание переменных в условии цикла Jopses PHP 3 12.05.2013 12:01
Крестики Нолики Бесконечное поле Progdog Общие вопросы C/C++ 3 19.06.2012 18:16
Бесконечное кол-во скролящихся эдитов :) flouwjke Общие вопросы Delphi 1 05.05.2012 22:34
Бесконечное проигрывание видео в фоне Lawilet JavaScript, Ajax 3 10.10.2011 13:42
Бесконечное открытие файлов Манжосов Денис :) БД в Delphi 9 23.11.2008 11:35