D
decay
Дописываю программу для работы с несколькими COM-портами. Сделал класс UniThread, и на его базе создал еще 2 класса ReadThread и WriteThread (итого в проге один главный поток и два моих). Все работало хорошо (пока реализации классов ReadThread и WriteThread были в одном модуле с реализацией класса ComPort), затем я выделил эти 2 класса в отдельные модули, немного подправил - и началось...
Посылаю данные в порт, на том конце их ловит микроконтроллер и отвечает эхом. Моя прога считывает их и записывает в консольку на форме (TMemo). Но принимает странно: то правильные данные, то какую-то чушь. Бывает, проскакивает какая-то хрень и в отправляемых данных, но это реже гораздо. Правильно принимает, если не двигать мышкой и не наводить ее на элементы управления формой (кнопки, комбобоксы и проч.). Если навести мышку на консольку TMemo и даже двигать при этом, то тоже работает без сбоев. Подозреваю, какая-то пробема с синхронизацией.
<!--shcode--><pre><code class='#CPP'>int ReadThread:rocCmds(void)
{
//int RXVal = 0;
unsigned int i=0;
unsigned char TempBuff[MAX_PACKET_LEN];
AnsiString CurrCmd;// = "";
//if (!itsLogFile) return 0;
while ( itsBuff->GetBufLen() >= PacketLen )
{
CurrCmd = "read: ";
for (i=0; i<PacketLen; i++)
{
itsBuff->Read(&TempBuff);
CurrCmd += IntToHex(TempBuff, 2) + " ";
}
//if (itsLogFile != FILE_FAIL) FileWrite(itsLogFile, TempBuff, itsRcvPacketLen);
/*
FormComTerm->mConsoleOut->Lines->Add(CurrCmd);
RXVal = StrToInt(FormComTerm->stRXd->Caption);
FormComTerm->stRXd->Caption = IntToStr(++RXVal);
*/
pConsole->Lines->Add(CurrCmd);
//RXVal = StrToInt(FormComTerm->stRXd->Caption);
//FormComTerm->stRXd->Caption = IntToStr(++RXVal);
}
return 0;
}
//------------------------------------------------------------------------------
DWORD ReadThread::MainFunc(void)
{
unsigned int AvaibleBytes;
unsigned char Buffer[10], RcvCmd[MAX_PACKET_LEN];
unsigned int i=0;//, BytesCnt=0;
DWORD dwWaitMutex, dwWaitPort;
DWORD Mask, RealRead, BytesTrans, Err;
OVERLAPPED ReadOL;
AnsiString CurrCmd = "read: ";
COMSTAT OwnersState;
memset(&ReadOL,0,sizeof(ReadOL));
ReadOL.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
SetCommMask(itsOwnersHandle , EV_RXCHAR);
while(!m_bTerminated)
{
//if ( !(itsOwner->Connected) ) goto finish; //hernya
if (itsOwnersHandle == NULL) return false;
WaitCommEvent(itsOwnersHandle, &Mask, &ReadOL);
dwWaitPort = WaitForSingleObject(ReadOL.hEvent, INFINITE);
if (dwWaitPort == WAIT_OBJECT_0)
{
if ( GetOverlappedResult(
itsOwnersHandle,
&ReadOL,
&BytesTrans,
FALSE)
)
{
if ((Mask & EV_RXCHAR))
{
ClearCommError (
itsOwnersHandle,
&Err,
&OwnersState
);
AvaibleBytes = OwnersState.cbInQue;
ReadFile(
itsOwnersHandle,
&Buffer,
AvaibleBytes,
&RealRead,
&ReadOL
);
i=0;
while (i<RealRead)
{
dwWaitMutex = WaitForSingleObject(PortMutex,INFINITE);
switch (dwWaitMutex)
{
case WAIT_OBJECT_0:
itsBuff->Write(Buffer);
ProcCmds();
//BytesCnt = 0;
if ( !ReleaseMutex(PortMutex) )
{
//ShowMessage("STOP thrd2");
}
break;
case WAIT_ABANDONED:
//cout << "aband ";
//the resource is busy, let's try it again at next time
break;
default:
//ReleaseMutex(itsOwner->hMutex)
//cout << "default ";
//break;
;
}
i++;
}
}
//RcvCnt += RealRead;
}
}
Sleep(1);
}
return 0;
}[/CODE]
Помогите разобраться с проблемой!
Посылаю данные в порт, на том конце их ловит микроконтроллер и отвечает эхом. Моя прога считывает их и записывает в консольку на форме (TMemo). Но принимает странно: то правильные данные, то какую-то чушь. Бывает, проскакивает какая-то хрень и в отправляемых данных, но это реже гораздо. Правильно принимает, если не двигать мышкой и не наводить ее на элементы управления формой (кнопки, комбобоксы и проч.). Если навести мышку на консольку TMemo и даже двигать при этом, то тоже работает без сбоев. Подозреваю, какая-то пробема с синхронизацией.
<!--shcode--><pre><code class='#CPP'>int ReadThread:rocCmds(void)
{
//int RXVal = 0;
unsigned int i=0;
unsigned char TempBuff[MAX_PACKET_LEN];
AnsiString CurrCmd;// = "";
//if (!itsLogFile) return 0;
while ( itsBuff->GetBufLen() >= PacketLen )
{
CurrCmd = "read: ";
for (i=0; i<PacketLen; i++)
{
itsBuff->Read(&TempBuff);
CurrCmd += IntToHex(TempBuff, 2) + " ";
}
//if (itsLogFile != FILE_FAIL) FileWrite(itsLogFile, TempBuff, itsRcvPacketLen);
/*
FormComTerm->mConsoleOut->Lines->Add(CurrCmd);
RXVal = StrToInt(FormComTerm->stRXd->Caption);
FormComTerm->stRXd->Caption = IntToStr(++RXVal);
*/
pConsole->Lines->Add(CurrCmd);
//RXVal = StrToInt(FormComTerm->stRXd->Caption);
//FormComTerm->stRXd->Caption = IntToStr(++RXVal);
}
return 0;
}
//------------------------------------------------------------------------------
DWORD ReadThread::MainFunc(void)
{
unsigned int AvaibleBytes;
unsigned char Buffer[10], RcvCmd[MAX_PACKET_LEN];
unsigned int i=0;//, BytesCnt=0;
DWORD dwWaitMutex, dwWaitPort;
DWORD Mask, RealRead, BytesTrans, Err;
OVERLAPPED ReadOL;
AnsiString CurrCmd = "read: ";
COMSTAT OwnersState;
memset(&ReadOL,0,sizeof(ReadOL));
ReadOL.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
SetCommMask(itsOwnersHandle , EV_RXCHAR);
while(!m_bTerminated)
{
//if ( !(itsOwner->Connected) ) goto finish; //hernya
if (itsOwnersHandle == NULL) return false;
WaitCommEvent(itsOwnersHandle, &Mask, &ReadOL);
dwWaitPort = WaitForSingleObject(ReadOL.hEvent, INFINITE);
if (dwWaitPort == WAIT_OBJECT_0)
{
if ( GetOverlappedResult(
itsOwnersHandle,
&ReadOL,
&BytesTrans,
FALSE)
)
{
if ((Mask & EV_RXCHAR))
{
ClearCommError (
itsOwnersHandle,
&Err,
&OwnersState
);
AvaibleBytes = OwnersState.cbInQue;
ReadFile(
itsOwnersHandle,
&Buffer,
AvaibleBytes,
&RealRead,
&ReadOL
);
i=0;
while (i<RealRead)
{
dwWaitMutex = WaitForSingleObject(PortMutex,INFINITE);
switch (dwWaitMutex)
{
case WAIT_OBJECT_0:
itsBuff->Write(Buffer);
ProcCmds();
//BytesCnt = 0;
if ( !ReleaseMutex(PortMutex) )
{
//ShowMessage("STOP thrd2");
}
break;
case WAIT_ABANDONED:
//cout << "aband ";
//the resource is busy, let's try it again at next time
break;
default:
//ReleaseMutex(itsOwner->hMutex)
//cout << "default ";
//break;
;
}
i++;
}
}
//RcvCnt += RealRead;
}
}
Sleep(1);
}
return 0;
}[/CODE]
Помогите разобраться с проблемой!