Re: Comm-port reader
От: Аноним  
Дата: 28.05.03 14:16
Оценка: 2 (1) +1
Здравствуйте, Mag, Вы писали:

Mag>Помогите с чтением из com-порта. Вот тривиальная задача.

Mag>Создаётся отдельный поток. Он выполняет следующие действия.
Mag>1. Открыть com-порт (CreateFile... — здесь всё просто).
Mag>2. Настроили порт, как надо (тут тоже не проблема).

Mag>Цикл:

Mag>3. Организуем ожидание события принятия байта из com-порта. Вот тут ключевая проблема. Должно быть что-то с WaitForSingleObject, WaitCommEvent или что-то ещё.
Mag>4. По принятию байта помещаем его в массив.

Mag>5. Закрываем com-порт.


Mag>Хитрость задачи состоит в том, что количество принимаемых байт не определено. Т.е. процесс приёма непрерывен: есть что-то — принимаем. Может есть у кого реально работающий кусок кода, реализующий поставленную задачу. Буду премного благодарен.




Простите, а в чем все таки проблема? Количество байт неопределено, но у Вас есть настраиваемый параметр сомм-порта ReadIntervalTimeout. Как только он истек, процедура чтения завершена. Параметр сколько байт надо прочитать из порта в функции ReadFile пусть будет большим, например размер буфера приемника. По окончании таймаута все что принято — все Ваше. Обработайте и возвращайтесь к ожиданию события приема символа и так бесконечно. А порт можно закрывать когда завершится поток чтения.
Второй вариант: как только случилось EV_RXCHAR вызовите ClearCommError и прочтите сколько байт уже поступило во "внутренний буфер" сомм-порта. Вызовите ReafFile с полученным параметром.


void CCommPort::InThread()
{
BOOL fSuccess=0;
DWORD nBytesRead=0,dwEvtMask=0,dwError=0,error=0,fRes=0;
COMSTAT Comstatus;
OVERLAPPED overlapped;

memset(&overlapped,0,sizeof(OVERLAPPED));
memset(&Comstatus ,0,sizeof(COMSTAT));

overlapped.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);

m_InBufNotEmpty =CreateEvent(NULL, TRUE, FALSE, NULL);
m_OutBufNotEmpty =CreateEvent(NULL, TRUE, FALSE, NULL);

m_InThreadIsLive=1;
m_nBytesRead=0;

int Ind = 0;

CRotorApp *pApp=NULL;
pApp=(CRotorApp *)AfxGetApp();

if(pApp==NULL)
{
//Ваша заглушка ошибки
return;
}

for(;)
{
nBytesRead=0;

m_Repeat=FALSE;

m_InThreadIsLive=1;

fRes=0;
fSuccess=0;

if(!ResetEvent(overlapped.hEvent))

{
//Ваша заглушка ошибки
}

if(!ResetEvent(m_InBufNotEmpty))
{
//Ваша заглушка ошибки
}

if(!WaitCommEvent(m_PortHandle, &dwEvtMask, &overlapped))
{
if(GetLastError()!=ERROR_IO_PENDING)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, 0, NULL );
AfxMessageBox((LPCTSTR)lpMsgBuf, MB_OK | MB_ICONINFORMATION );
FinishInThread();
}
WaitForSingleObject(overlapped.hEvent,INFINITE);
}

if (dwEvtMask & EV_BREAK)
{
//Ваша заглушка ошибки
}
else
if (dwEvtMask & EV_RXCHAR)
{
ClearCommError(m_PortHandle,&dwError,&Comstatus);

if(!ResetEvent(overlapped.hEvent))
{
//Ваша заглушка ошибки
}

if(!ReadFile(m_PortHandle,
&m_InBuffer[Ind],
MAX_BUFFER_SIZE,//Comstatus.cbInQue,
&nBytesRead,
&overlapped))
{
if(GetLastError()!=ERROR_IO_PENDING)
{
//Ваша заглушка ошибки
}

fRes=WaitForSingleObject(overlapped.hEvent,7000);

switch(fRes)
{
case WAIT_OBJECT_0:
if(!GetOverlappedResult(m_PortHandle, &overlapped, &nBytesRead, FALSE))
{
//Ваша заглушка ошибки
}
break;
case WAIT_TIMEOUT:
break;
default:
//Ваша заглушка ошибки
break;
}
}


if(!ResetEvent(overlapped.hEvent))
{
//Ваша заглушка ошибки
}
if(nBytesRead>0)
{
//Можно обрабатывать сообщение
}
}
}
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.