Автор
|
Тема: WaitForSingleObject
|
MrSergei |
опубликован 11-01-2002 03:46 MSK
Мне необходимо отловить сигнал с внешнего устройства, которое подключено к компу через COM1, при помощи WaitForSingleObject, т.к. если устройство в течении положенного времени (5 секунд к примеру) не посылает сигнала на комп, то необходимые процедуры не выполняются. Но устройство может посылать только сигнал типа EV_ERR, а его WaitForSingleObject у меня не отлавливает, как быть, и что нужно заменить в коде чтоб заработало? HANDLE port; BOOL fSuccess; OVERLAPPED event;
// Заполнение dcb и прочей ерунды port=CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); fSuccess = SetCommMask(port, EV_ERR); event.hEvent = CreateEvent( NULL, FALSE, TRUE, NULL ); if (WaitForSingleObject(event.hEvent, 5000) == WAIT_OBJECT_0) { // ПроцеДура } else AfxMessageBox("Нет сигнала от устройства");
|
Rush
|
опубликован 11-01-2002 03:52 MSK
что то типа SetCommEvent |
MrSergei
|
опубликован 11-01-2002 04:50 MSK
Я знаю про WaitCommEvent, про Set... ничего. Но не в них дело, мне необходимо ждать сигнала от устройства в течении определенного времени, а WaitCommEvent будет ждать вечно, но правда если сигнал есть, то все нормально, но надо обработать и случай если сигнала нет (ждать в течении 5-ти секунд), всякое случается. Может какую структуру надо заполнить, или че-нить изменить надо в коде? |
Jack
|
опубликован 11-01-2002 09:49 MSK
Извиняюсь, что не совсем по теме, но у меня вопрос: а как устройство посылает этот сигнал EV_ERR ? Если верить MSDN, то EV_ERR означает "line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY." Как "некривое" устройство сформирует такое ? |
the_moon
|
опубликован 11-01-2002 10:53 MSK
Вот прога которая запускает процесс и ждет сколько надо, а потом убивает процесс, анологично будет наверное и для потока. .....................
#include "afx.h" #include "stdio.h" int main( int argc, char** args ) { if( 3 > argc ) { printf( "2 parameters needed:\n" "\t time in seconds\n" "\t command string ( full qualified file name )\n" );
return 1; } int Seconds = atoi( args[1] ); if( 0 == Seconds ) { printf("Incorrect time : %d\n", Seconds ); return 2; } CTime EndTime = CTime::GetCurrentTime() + CTimeSpan( Seconds ); //Start command
PROCESS_INFORMATION pi; STARTUPINFO si; memset( &si,0, sizeof( STARTUPINFO ) ); si.cb = sizeof(STARTUPINFO); memset( &pi,0, sizeof( PROCESS_INFORMATION ) ); if( !CreateProcess(NULL, args[2] ,NULL,NULL,TRUE, CREATE_NEW_CONSOLE | CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS ,NULL, NULL /* _current_path */, &si, &pi)) { printf("Cannot start %s\n", args[2] ); return 3; } //Wait process DWORD ECode;
while( GetExitCodeProcess( pi.hProcess, &ECode ) ) { Sleep(100); if( STILL_ACTIVE == ECode ) { if( CTime::GetCurrentTime() > EndTime ) { // The time is out, kill process TerminateProcess( pi.hProcess, 4 ); return 4; } } else { return 0; } } return 0; }
|
MrSergei
|
опубликован 11-01-2002 18:37 MSK
Вот полностью процедура, которая у меня выделена как поток, взаимодействующая с портом. В таком виде у меня все работает, но нет времени ожидания. Устройство посылающее сигнал и впрям кривое, не я делал (просто не умею:), оно осуществляет поворот зеркала в другом устройстве, но не это главное, оно посылает на порт именно сигнал ошибки - EV_ERR, вот если бы EV_DSR, то WaitForSingleObject сработала бы, и не надо было бы использовать WaitCommEvent, но электронщик не хочет перепайкой заниматься. Как отловить сигнал EV_ERR при помощи WaitForSingleObject? Или может быть что-нить другое использовать? UINT CommActivate(LPVOID pParam) { HANDLE port; DWORD bc; DCB dcb; char buffer[100]; DWORD dwBlockSize=512; void *szBuffer; int zapros=255; BOOL fSuccess; OVERLAPPED event; DWORD dwEvtMask;
ZeroMemory(&dcb,sizeof(DCB)); strcpy(buffer,"baud=1200 parity=N data=8 stop=1"); BuildCommDCB((char*)&buffer,&dcb); dcb.fRtsControl = RTS_CONTROL_ENABLE; port=CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); GetCommState(port,&dcb); if(port==INVALID_HANDLE_VALUE) { AfxMessageBox("Не возможно открыть последовательный порт"); ExitProcess(1); } SetCommState(port,&dcb); HeapFree(GetProcessHeap(),0,&dcb); //Запрос на устройство //в виде числа 255 szBuffer = malloc(dwBlockSize); memset(szBuffer, zapros, dwBlockSize); WriteFile(port,szBuffer,sizeof(szBuffer),&bc,NULL); free(szBuffer); fSuccess = SetCommMask(port, EV_ERR); event.hEvent = CreateEvent( NULL, FALSE, TRUE, NULL ); //Ожидание ответного сигнала от устройства // if (WaitForSingleObject(event.hEvent, 5000) == WAIT_OBJECT_0) // { if (WaitCommEvent(port, &dwEvtMask, &event)) { if (dwEvtMask & EV_ERR) { // Какое-нибудь действие } } // } // else AfxMessageBox("Связь с устройством не установлена!"); CloseHandle(port); CloseHandle(event.hEvent) return 0; } |
Jack
|
опубликован 11-01-2002 20:49 MSK
Я немного электронщик и берусь утверждать, что послать на СОМ-порт "сигнал" EV_ERR невозможноб поскольку в разъеме RS232 (COM1) такого сигнала нет (если ошибаюсь, сильно не бейте). Но можно каким-либо образом COM-порт заставить его сформировать, но насколько этот изврат будет стабильно работать ???. Лучше всего, конечно, напрячь "электронщика" на перепайку. Если-же это совсем невозможно, попробуй узнать у него КАК он формирует этот сигнал. Зная это могу попробовать промоделировать у себя твою ситуацию. Хотя надеюсь, что кто-нибудь подскажет что-нибудь более полезное. |
Jack
|
опубликован 14-01-2002 08:22 MSK
В выходные, (после спиртного) появилась идея:OVERLAPPED ovl; ovl.Offset = 0; ovl.OffsetHigh = 0; ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); DWORD mask; WaitCommEvent(port, &mask, &ovl); WaitForSingleObject(ovl.hEvent, 5000); if (mask &EV_ERR) { ....... } |
MrSergei
|
опубликован 15-01-2002 03:26 MSK
Спасибо, в четверг схожу на работу- проверю. |