Re: Highly responsive serial port
- From: "Arkej" <NOSPAMrobert.krt@xxxxxxxxxxxxxxxxxxx>
- Date: Tue, 5 Aug 2008 14:14:36 +0200
Thanks for the link.
I forgot to mention I'm using overlaped readfile with the
waitforsingleobject... Here is the Reader function(the one that gets called
in the loop):
int CCOMreader::Read()
{
DWORD dwError;
DWORD dwRes;
COMSTAT pStat;
bool bResult;
if (bReadWaiting)
{//if previous read hasn't finish return
if ((dwRes = WaitForSingleObjectEx( hReadCompleted, 0, FALSE)) !=
WAIT_OBJECT_0)
{
return 0;//read still in progress
};
if (!GetOverlappedResult(hStream, &olRead, &nBytesRead, TRUE))
{
char cstrTemp[80];
sprintf(cstrTemp, "Read GetOverlappedResult error: %d", GetLastError());
Output(cstrTemp);
};
bReadWaiting = false;//reading finished
ResetEvent(olRead.hEvent);
};
//dump the buffer into log
if (nBytesRead > 0)
{
Output("iC:" + DumpData((BYTE *)bufMsg, nBytesRead));
ZeroMemory(bufMsg,sizeof(bufMsg));
nBytesRead = 0;
};
//if anything on the device call ReadFile asynchronously
ClearCommError( hStream, &dwError, &pStat);
if( dwError )
{
char strE[80];
ZeroMemory(strE,sizeof(strE));
sprintf( strE, "ERR: dwError on comm port check == 0x%08x", dwError);
Output(strE);
}
if (pStat.cbInQue > 0) //read if anything
{
bResult = ReadFile( hStream,
bufMsg,
pStat.cbInQue,
&nBytesRead,
&olRead
);
if (!bResult)
{
dwError = GetLastError();
if (dwError != ERROR_IO_PENDING)
{
char strE[100];
ZeroMemory(strE,sizeof(strE));
sprintf( strE, "ERR: FATAL I/O Error %ld I/O Context %lx.%lx\n",
dwError, &(olRead), olRead.hEvent);
Output(strE);
}
else
{
bReadWaiting = true;//overlapped read in process
};
};
};
}
"Pavel A." <pavel_a@xxxxxxxxxxxxxxx> wrote in message
news:uLJUxLv9IHA.3344@xxxxxxxxxxxxxxxxxxxxxxx
Yes, sleep(1) will make you wait for too long.
Maybe you need here ReadFileEx with asynchronous callbacks, or overlapped
ReadFile & WaitForSingleObject with timeout
On this page http://www.lvr.com/serport.htm
you can find more info on serial ports under Windows.
Regards,
--PA
Arkej wrote:
Pavel,
thank you for your hints. What I did in my test with timeouts was to set
ReadIntervalTimout = MAXDWORD to make a call to Readfile function return
immediately. That's all I do with timeouts.
As described in reply above this thread I then read in a loop using
ClearCommError to get the status of the device and read asynchronously
the bytes. Realtime priority gave some results but still sometimes there
were delays(I guess sleep(1) is the most delaying line in my code but
also without it there are still delays and the system gets
nonresponsive). I'm already looking for a hw/sw solution but I need a
quick one now until the hw(microcontroller) is built.
Regards,
Robert
"Pavel A." <pavel_a@xxxxxxxxxxxxxxx> wrote in message
news:%23osAvHm9IHA.4092@xxxxxxxxxxxxxxxxxxxxxxx
In addition to other replies:
Note that read request to the serial driver can be completed
by reading specified number of bytes, or by timeout.
In it's turn, the resolution of these timeouts is same as the
system clock resolution.
So, you either don't want to rely on timeouts (design your protocol
so that request can be completed by reading exact number of bytes)
or set the minimum possible timer resolution (which may be ~ 2ms)
and use short timeouts.
Giving your process realtime priority is pointless
without this, because what holds your process is waiting for
i/o completion, not other processes.
Also, for real time serial protocols I'd warmly recommend
a cheap programmable microcontroller, connected to PC
over USB, ethernet or even serial port (not in real-time, of course).
Regards,
--PA
Arkej wrote:
Hello,
before I dive into the world of kernel mode drivers I'd like to know:
My problem consists of reading from a serial COM port as fluent as
possible(real-time like). It looks like it is not doable in user mode.
If due to scheduling of threads my reader thread doesn't get enough
time I have a delay of read on the input. Let's say I have to process
data coming every 30ms and then reply in 20ms. If my reader only reads
the input buffer after 50ms I'm too late to reply but I don't know it.
1. Would a driver(in kernel mode) have enough priority to process such
requests in time?
2. Is there any other way in user mode to assure constant read of
serial port?
Thanks
Robert
.
- References:
- Highly responsive serial port
- From: Arkej
- Re: Highly responsive serial port
- From: Pavel A.
- Re: Highly responsive serial port
- From: Arkej
- Re: Highly responsive serial port
- From: Pavel A.
- Highly responsive serial port
- Prev by Date: Re: Highly responsive serial port
- Next by Date: WDF - User Mode Driver Framework - COM port driver
- Previous by thread: Re: Highly responsive serial port
- Next by thread: Re: Highly responsive serial port
- Index(es):
Relevant Pages
|