|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
ошибка при чтении данных с Com порта, просто проверте небольшой код на ошибки
Всем доброго времени суток.
Опишу все вкратце Задача такова: на порт приходят приерно раз в секунду несколько байтов данных использую с++ builder 6 (пробовал этот же проект в 2010 , ситуация та же), пользуюсь функциями из SDK(правильно ли оперирую терминами , поправьте если что) код собран из примеров http://msdn.microsoft.com/en-us/library/ms810467.aspx может важно а может нет - на компьютере нет com порта!! , для эмуляции всего процесса используется программа VSPD которая создает два порта и программа PROTEUS которая эмулирует устройство на эти вещи не грешу - изначально делал в NONOVERLAPPED режиме и данные читались без проблем НО как оказалось, это дубовый способ, ибо я жду прерывания (раз в секунду же) , а если ничего не приходит (сломалось устройство оторвался провод...) то функция WaitCommEvent будет ждать ждать ждать... причем если делать чтение в отделном потоке а потом его пытатся завершить то виснет и основной поток поэтому решил делать в OVERLAPPED режиме(ну и тоже в отделном потоке) , но тут возникает непонятная проблема - вроде все как показано на ссылке выше, НО функция чтения ReadFile возвращает false а функция GetLastError возвращает 998 ошибку (error_noaccess) порядок действий в коде ниже таков: создаем хендл для чтения (типа открываем файл с именем "COM7" скажем) устнавливаем настройки (может тут где проблема) bcb структура , временные интервалы для чтения, тип прерывания,OVERLAPPED структура далее в цикле WaitCommEvent возвращает ERROR_IO_PENDING и начинаем ждать функцией WaitForSingleObject когда они прибудут данные прибыли , функция возвратила WAIT_OBJECT_0 и мы ждем функцией GetOverlappedResult когда будут прочитан байт вот тут самое интересное - функция возвращает true и numbytes_ok содержит "4" ,хотя во-первых я посылаю 6 байт(5 и символ перевода строки) а во-вторых GetOverlappedResult выполняется после каждого принятого байта причем читается всего 5 байтов!! вызываем функцию ReadFile , она возвращает FALSE а GetLastError возвращает ошибку 998(error_noaccess) numbytes_ok после этого равна 0 и причем numbytes_ok = 4 устанавливается после первого же принятого байта (точнее после первого захода в WAIT_OBJECT_0 из пяти между секундными интервалами) какие либо перестановки в коде ничего толком не дали, если все элементы не принадлежащие потоку засунуть в метод и вызывать через Synchronize то ситуация все та же в общем наверно где-то допустил тупую ошибку и прошу беглым взглядом проверить сведущих людей данный код заранее спасибо! Код:
DCB dcb; _COMSTAT ComState; DWORD numbytes_ok; DWORD dwEvtMask; HANDLE hCom = CreateFile( portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ); READ = GetCommState(hCom, &dcb); dcb.BaudRate = 9600; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; READ = SetCommState( hCom, &dcb ); COMMTIMEOUTS CT; GetCommTimeouts( hCom, &CT) ; CT.ReadIntervalTimeout = 1; CT.ReadTotalTimeoutMultiplier = MAXDWORD; CT.ReadTotalTimeoutConstant = MAXDWORD; SetCommTimeouts( hCom, &CT ); if (!SetCommMask(hCom,EV_RXCHAR)) Form1->Memo1->Lines->Add("error setting communications mask; abort"); int STATUS_CHECK_TIMEOUT =1300 ; // Milliseconds DWORD dwCommEvent; BOOL fWaitingOnStat = FALSE; OVERLAPPED osStatus ; osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (osStatus.hEvent == NULL) Form1->Memo1->Lines->Add("error creating event; abort"); if(READ)Form1->Memo1->Lines->Append("ОК"); char *buf_in; while (!Thr->Terminated && READ) { if (!fWaitingOnStat && !Thr->Terminated) { if (!WaitCommEvent(hCom, &dwCommEvent, &osStatus)) { if (GetLastError() == ERROR_IO_PENDING) { Form1->Memo1->Lines->Add("ERROR_IO_PENDING"); fWaitingOnStat = TRUE; // Form1->Memo1->Lines->Add(AnsiString(numbytes_ok)+" "+ "0"); } else { Form1->Memo1->Lines->Add(" error in WaitCommEvent; abort"); break; } } else { Form1->Memo1->Lines->Add("WaitCommEvent returned immediately"); } } // Check on overlapped operation. if (fWaitingOnStat && READ) { switch(WaitForSingleObject(osStatus.hEvent, STATUS_CHECK_TIMEOUT)) { case WAIT_OBJECT_0: if (!GetOverlappedResult(hCom, &osStatus, &numbytes_ok, TRUE)) { Form1->Memo1->Lines->Add("An error occurred in the overlapped operation"); } else { /////////////////////////////////////////////////////////////////////////////////READING if(ReadFile(hCom, buf_in, 1, &numbytes_ok, &osStatus)) { Form1->Memo1->Lines->Add(buf_in); } else { Form1->Memo1->Lines->Add(GetLastError()); } Form1->Memo1->Lines->Add(numbytes_ok); } fWaitingOnStat = FALSE; break; case WAIT_TIMEOUT: Form1->Memo1->Lines->Add("WAIT_TIMEOUT"); break; default: Form1->Memo1->Lines->Add("CloseHandle"); CloseHandle(osStatus.hEvent); } } } |
#2
|
|||
|
|||
Это же на С/С++ написано? А этот форум посвящен Delphi.
|
#3
|
||||
|
||||
Переводи
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |