 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Neil P. Guest
|
Posted: Mon May 09, 2005 5:40 pm Post subject: Response not in que? |
|
|
I am not sure if this is the right newsgroup, but I don't know where to post
this one?
I have an application where I write to the comm port and read from it. I am
currently experiencing a problem, where I send a byte then wait for the unit
to respond with a byte, but it gets there about 10 secs later.
I am looking at the que, to signal if there is something to read, but
nothing gets qued? I know that the other system is sending it immediately
(less than 1 sec) after it recieves my byte.
What could be happening? Is there a priority setting I am suppose to set to
make my communication priority over a mouse movement or any other system
process?
Thank you,
Neil P.
|
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Mon May 09, 2005 8:15 pm Post subject: Re: Response not in que? |
|
|
Neil P. wrote:
| Quote: | I have an application where I write to the comm port and read from it. I am
currently experiencing a problem, where I send a byte then wait for the unit
to respond with a byte, but it gets there about 10 secs later.
|
Sounds like a time-out. How are you trying to read it?
Are you sure you're only asking for a one byte read?
| Quote: | I am looking at the que, to signal if there is something to read, but
|
How are you doing that?
| Quote: | nothing gets qued? I know that the other system is sending it immediately
(less than 1 sec) after it recieves my byte.
|
|
|
| Back to top |
|
 |
Neil P. Guest
|
Posted: Mon May 09, 2005 8:31 pm Post subject: Re: Response not in que? |
|
|
I use ClearCommError(hComm, &dwErrorMask, & Comstat)
to view what is coming in the cbInQue,
Once, I detect there is something in the que, I
use ReadFile(hComm, inbuff, nBytes, &nBytesRead, &overlapped), I am in this
routine upto 2 times the amount of bytes coming in, using my baudrate 9600.
So I beleive there is plenty of time so that byte can be placed in the que
buffer.
If the unit sending the byte responds ( in a millisecond), then how long is
it before Windows reports to the ClearCommError or to the struct_COMSTAT
that there is a byte waiting? Does Windows take more than a second to place
it on the que?
By the way the unit is always responding with one byte, because is the
response of what I am sending it.
Thank you,
Neil P.
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Mon May 09, 2005 8:57 pm Post subject: Re: Response not in que? |
|
|
"Neil P." <nporve01 (AT) hotmail (DOT) com> wrote
| Quote: | I use ClearCommError(hComm, &dwErrorMask, & Comstat)
to view what is coming in the cbInQue,
|
When do you call it, though? Are you checking for errors? Please show a
code snippet of what you are actually doing.
Rather than using ClearCommError(), why not just read immediately after
writing? You are already expecting a byte to be written, so just read
immediately and let the reading block until the byte actually arrives. It
also looks like you are using overlapped I/O, which played directly in my
suggestion as well, since ReadFile() will return immediately and then you
can use WaitForSingleObject() to wait for the reading to signal the event
object that you place in your OVERLAPPED structure.
Gambit
|
|
| Back to top |
|
 |
Neil P. Guest
|
Posted: Mon May 09, 2005 8:57 pm Post subject: Re: Response not in que? |
|
|
Well, I am using overlapped I/O. The problem is that I don't want my code
to lock up.
If the other unit does not respond, I want the read function to quit, but
what is a good time to quit?
How about if I dishout an application that works well with this unit, under
the environment I am in, but
when the user gets it, the unit or my application seems that it is lockout
(because he/she has a pentium 100, operating on Win95)? <---- Just an
example.
I was using the WaitForSingleObject(), but it did not make a difference,
where I enabled it or not?
Anyways, lets see if I can display a snippet from my code.
Thank you,
Neil P.
"Remy Lebeau (TeamB)"
| Quote: |
"Neil P." <nporve01 (AT) hotmail (DOT) com> wrote in message
news:427fca8b$1 (AT) newsgroups (DOT) borland.com...
I use ClearCommError(hComm, &dwErrorMask, & Comstat)
to view what is coming in the cbInQue,
When do you call it, though? Are you checking for errors? Please show a
code snippet of what you are actually doing.
Rather than using ClearCommError(), why not just read immediately after
writing? You are already expecting a byte to be written, so just read
immediately and let the reading block until the byte actually arrives. It
also looks like you are using overlapped I/O, which played directly in my
suggestion as well, since ReadFile() will return immediately and then you
can use WaitForSingleObject() to wait for the reading to signal the event
object that you place in your OVERLAPPED structure.
Gambit
|
|
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Mon May 09, 2005 9:21 pm Post subject: Re: Response not in que? |
|
|
Neil P. wrote:
| Quote: | I use ClearCommError(hComm, &dwErrorMask, & Comstat)
to view what is coming in the cbInQue,
|
Have no idea why you would use that along with overlapped i/o?
If you aren't using overlapped i/o then remove it from your ReadFile()
It should be NULL unless you are using actually using it.
| Quote: | Once, I detect there is something in the que, I
use ReadFile(hComm, inbuff, nBytes, &nBytesRead, &overlapped), I am in this
routine upto 2 times the amount of bytes coming in, using my baudrate 9600.
|
So, again, I'll ask...What is the value of nBytes? Is it 1 or 2?
If you are trying to read more bytes than are available, it will wait
for more bytes to arrive (or time out after some amount of time [10
seconds? See GetCommTimeouts() ] ).
| Quote: | So I beleive there is plenty of time so that byte can be placed in the que
buffer.
|
Does ReadFile() return True or False?
If False, have you checked the value of GetLastError()?
| Quote: | If the unit sending the byte responds ( in a millisecond), then how long is
it before Windows reports to the ClearCommError or to the struct_COMSTAT
that there is a byte waiting? Does Windows take more than a second to place
it on the que?
|
I don't know, never used it, but I'd expect it to be immediate.
|
|
| Back to top |
|
 |
Neil P. Guest
|
Posted: Mon May 09, 2005 9:28 pm Post subject: Re: Response not in que? |
|
|
Here is a snippet of my code and exactly what I am doing:
1. Is where I am writing and reading.
2. Is my actual read.
// Set the unit on programming mode
clComm.Write("C",1);
do
{
clComm.Read(1);
cResponse = NULL;
cResponse = clComm.cTransBuff;
if (iRead_Tries >= 3)
goto No_Response;
iRead_Tries++;
}
// Wait for 0x0D
while (cResponse[0] != 0x0D);
//--------------------------------------------------------------------------
----
// Read from COM port
//--------------------------------------------------------------------------
----
void __fastcall Comm::Read(unsigned int iExpected)
{
// Initialize
iCollectBytes = 0;
dwActualBytesRead = 0;
bStop_Read = false;
COMSTAT comstat; // Structure of the communication device
// Do we have the handle ?
if (hComm)
{ // Begin if statement (Handle)
// Clear the buffers
for (int i = 0; i <= (BUFSIZE - 1); i++)
bCommData[i] = NULL;
for (int i = 0; i <= (BUFSIZE - 1); i++)
cTransBuff[i] = NULL;
// Set a safety timeout
dwRead_Time_Out = GetTickCount() + (iExpected*2);
// Stop read flag
while (bStop_Read == false)
{ // Begin while statement (Stop Read Flag)
// Do we have the handle ?
//if (hComm)
// Clear any communication error & return # of bytes in the input
buffer
ClearCommError(hComm, // handle to communications device
&dwError, // pointer to variable to receive error
codes
&comstat); // pointer to buffer for communications
status
// Is there anything waiting to be read (BUFSIZE bytes match
cCommData
//capability)
if ((comstat.cbInQue >= iExpected) && (comstat.cbInQue <= BUFSIZE))
{ // Begin if statement (InQue)
// Do we have the handle ?
//if (hComm)
// Read the data from the serial port
if (!ReadFile (hComm,
bCommData,
comstat.cbInQue,
&dwBytesTransferred,
&o))
{ // Begin if statement (read error)
// Check if error is Overlapped I/O pending
if (!(GetLastError() == ERROR_IO_PENDING))
// Report the error
ReportError();
} // End if statement (read error)
else
{ // Begin else statement (Bytes are waiting)
// Return the number of bytes that were read
GetOverlappedResult(hComm,
&o,
&dwActualBytesRead,
FALSE);
// Are there bytes waiting and check if buffer is not overrun
if ((dwActualBytesRead != 0) && (dwActualBytesRead <= BUFSIZE))
{ // Begin if statement (actual bytes read)
// Start the collection of bytes
for (unsigned int i = 0; i <= (dwActualBytesRead - 1); i++)
{ // Begin for statement (byte collect)
// Copy the data to the return variable
cTransBuff[iCollectBytes++] = bCommData[i];
} // End for statement (byte collect)
} // End if statement (actual bytes read)
} // End else statement (Byte are waiting)
} // End if statement (InQue)
// Safety timeout check
if (dwRead_Time_Out <= GetTickCount())
// End the read while loop
bStop_Read = true;
} // End while statement (Stop Read Flag)
} // End if statement (Handle)
}
It probably looks pretty weird, but I am not an expert. It works if
iRead_Tries is a number like 10, but that means according to my code that if
I am running my communication at 9600 baud, and I am expecting 1 byte and I
am multiplying by two, enough so that it will read it the first time and not
even have to get to three.
So I believe, that Windows does not report right away to the struct
__COMSTA, there is actually a delay of some sort? I can't put my finger on
it, but maybe you guys can see something I am doing wrong with this snippet
of code.
By the way, I am not always expecting one byte coming back, that is why, my
readfile has comstat.cbInQue, as the number of bytes to read.
Thank you,
Neil P.
|
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Mon May 09, 2005 10:03 pm Post subject: Re: Response not in que? |
|
|
Neil P. wrote:
| Quote: | Well, I am using overlapped I/O. The problem is that I don't want my code
to lock up.
|
It won't lock up.
WaitForSingleObject() has a timeout value.
You should be running all this an a worker thread so the GUI stays
available to the user in any case.
If you want to use blocking reads/writes instead of overlapped
(blocking is easier to write and understand), then set a reasonable
timeout with SetCommTimeouts() so you don't lock up.
| Quote: | If the other unit does not respond, I want the read function to quit, but
what is a good time to quit?
|
Well, you expect to get a result in < 1 sec, so 2 second timeout seems
safe. The speed of the CPU is mostly irrelevant at 9600 baud, unless
you are talking less than 1 MHz.
WriteFile( f, "t", 1, &written, &overlap );
status = WaitForSingleObject( hCommEvent, 1000 );
if( status != WAIT_OBJECT_0 )
{ /*handle the write error*/
}else{
GetOverlappedResult(.....);
/* double check the write completed */
ReadFile( f, buf, 1, &read, &overlap );
status = WaitForSingleObject( hCommEvent, 2000 );
if( status != WAIT_OBJECT_0 )
{ /*handle the read error*/
}else{
GetOverlappedResult(.....);
/* double check the read */
};
};
|
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Mon May 09, 2005 10:26 pm Post subject: Re: Response not in que? |
|
|
Neil P. wrote:
| Quote: | do
{
clComm.Read(1);
cResponse = NULL;
|
Why the double assign?
| Quote: | cResponse = clComm.cTransBuff;
// Clear the buffers
for (int i = 0; i <= (BUFSIZE - 1); i++)
bCommData[i] = NULL;
|
// Clearer Clear the buffers
memset( bCommData, 0, sizeof(bCommData) );
| Quote: | // Set a safety timeout
dwRead_Time_Out = GetTickCount() + (iExpected*2);
|
The first data won't arrive for .001042 seconds, so you are leaving
only .000958 seconds for the device to get the character you sent and
respond. Also, realise that the counter isn't all that accurate to
begin with. Example: First call is at 1.001999 and shows 1.001, that
leaves you with less than 1 character-time before you time out.
To be fair to the device, you would need to allow 1.042 msec per
character sent, plus reasonable processing time, plus the same amount
times chars to receive. Also, some devices don't send at full baud
rate. I've see 50% duty cycles on some devices (one full char-time
between chars).
| Quote: | while (bStop_Read == false)
{
// Clear any communication error & return # of bytes in the input
buffer
ClearCommError(hComm, &dwError, &comstat);
|
See other message.
| Quote: | GetOverlappedResult(hComm,
&o,
&dwActualBytesRead,
FALSE);
// Are there bytes waiting and check if buffer is not overrun
if ((dwActualBytesRead != 0) && (dwActualBytesRead <= BUFSIZE))
|
Not right. Can overflow cTransBuf. Also discards data and perhaps
causes timeout because you threw away the data you were waiting for.
| Quote: | { // Begin if statement (actual bytes read)
// Start the collection of bytes
for (unsigned int i = 0; i <= (dwActualBytesRead - 1); i++)
{ // Begin for statement (byte collect)
// Copy the data to the return variable
cTransBuff[iCollectBytes++] = bCommData[i];
|
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Mon May 09, 2005 11:34 pm Post subject: Re: Response not in que? |
|
|
"Neil P." <nporve01 (AT) hotmail (DOT) com> wrote
| Quote: | Well, I am using overlapped I/O. The problem is that I don't
want my code to lock up.
|
The thing about overlapped I/O is that you don't have to lock up your code.
Once you call ReadFile(), specifying an OVERLAPPED structure, ReadFile()
will return immediately and your code can go off to do other things while
the reading happens in the background. Then your code can periodically
check the status of the event object inside the OVERLAPPED structure when it
has a chance to. Once the event has been signaled, the reading has finished
and you can use GetOverlappedResult() to find out the result of the reading.
| Quote: | If the other unit does not respond, I want the read function to quit,
but what is a good time to quit?
|
Your use of CheckCommStatus() to poll the serial port status could be
slowing the code down. If you get rid of it entirely and just let the
overlapped I/O do the work for you, you'll probably notice that your unit's
responses come through a lot faster. You know that the unit should be
sending a byte back to you, so just perform an overlapped reading
immediately after you finish writing, and you will still be able to detect
when the reading has completed.
| Quote: | How about if I dishout an application that works well with this unit,
under the environment I am in, but when the user gets it, the unit or
my application seems that it is lockout
|
That would suggest to me that your code is not set up to handle the serial
port properly.
| Quote: | because he/she has a pentium 100, operating on Win95
|
Overlapped I/O on a serial port works fine on Win9x.
Gambit
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Mon May 09, 2005 11:39 pm Post subject: Re: Response not in que? |
|
|
"Bob Gonder" <notbg (AT) notmindspring (DOT) invalid> wrote
| Quote: | // Clearer Clear the buffers
memset( bCommData, 0, sizeof(bCommData) );
|
Since he did not show what bCommData is actually declared as, it would be
safer to do the following:
memset(bCommData, 0, BUFSIZE);
Gambit
|
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Tue May 10, 2005 3:31 am Post subject: Re: Response not in que? |
|
|
Remy Lebeau (TeamB) wrote:
| Quote: | "Bob Gonder" wrote in message
// Clearer Clear the buffers
memset( bCommData, 0, sizeof(bCommData) );
Since he did not show what bCommData is actually declared as, it would be
safer to do the following:
memset(bCommData, 0, BUFSIZE);
|
That was my original thought, but then decided bCommData might be
other than Byte in size. Since he was setting bCommData[i]=0, if it
was made of wchar or ints, then you'd only zero 1/2 or 1/4 of them.
How about
memset(bCommData, 0, BUFSIZE * sizeof( bCommData[0]) );
|
|
| Back to top |
|
 |
Neil P. Guest
|
Posted: Wed May 11, 2005 1:38 pm Post subject: Re: Response not in que? |
|
|
I like to thank everyone for helping me.
I hope the code snippet did not confuse anyone, and I know I might not be
doing things right, but I am trying to correct my mistakes.
I don't use CheckCommStatus() anywhere in my snippet?
| Quote: | Your use of CheckCommStatus() to poll the serial port status could be
slowing the code down. If you get rid of it entirely and just let the
overlapped I/O do the work for you, you'll probably notice that your
unit's
responses come through a lot faster. You know that the unit should be
sending a byte back to you, so just perform an overlapped reading
immediately after you finish writing, and you will still be able to detect
when the reading has completed.
Gambit
|
Let me explain, a little more to see if my problem becomes a whole lot
clearer for everyone.
I have developed a unit that talks with a software application using
commport 1 or COM1.
The embeded unit and pc software is communicating @ 9600 baud. The pc
software is the
master and the embeded unit is a slave. I poll the embeded unit and it
responds ( < 1ms) for
all intend and purposes. I tested the respond time of the embeded unit
using Hyperterminal and
it never fails ( < 1ms) you can't even time it, if all your using is
Hyperterminal, just see that it always
respond immediately. Now, if Hyperterminal is using the same baud rate and
same settings as my
application, I expect my application to behave the same way.
Yet what I find, is that in the snippet I sent if I write a little more test
code, where I increment a counter
to see how many attempts it takes to recieve the information coming from the
embeded unit, I find that
it sometimes takes more than 3 tries, sometimes more than 10 tries, before
the unit comes out of the loop.
The question is why? The information should be there almost instantly.
This is my calculations,
9600 baud = 104.16 us per bit, if I am recieving just one byte coming back,
104.16 uS x 8bits = 833.28 uS
in my code snippet, I use GetTickCount to start a timer of the number of
bytes expected and I go ahead and multiply it by 2, so at to give it even
more time. So if I am doing things correctly, I should have 833.28uS x 2
1.66Sec approximately double the time it would take for that byte to
actually get Windows to pick up the byte and have it ready for me to read
it?
I go a step further and give the application an extra three times to try and
it still fails?
I don't understand why? Everything tells me the byte should be there and
maybe it is, but definetly I am doing something terribly wrong in my Read
snippet, because I am not getting that byte????
Can you guys look at my snippet and see what I am doing wrong, I have no
idea, I have tried everything I know?
Thank you,
Neil P.
|
|
| Back to top |
|
 |
Jonathan Benedicto Guest
|
Posted: Wed May 11, 2005 1:56 pm Post subject: Re: Response not in que? |
|
|
"Neil P." <nporve01 (AT) hotmail (DOT) com> wrote
| Quote: |
Can you guys look at my snippet and see what I am doing wrong, I
have no
idea, I have tried everything I know?
|
You could use a third-party VCL component for this task. Look here
http://www.torry.net/pages.php?id=198 for a couple of free ones.
HTH
Jonathan
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Wed May 11, 2005 5:06 pm Post subject: Re: Response not in que? |
|
|
"Neil P." <nporve01 (AT) hotmail (DOT) com> wrote
| Quote: | I don't use CheckCommStatus() anywhere in my snippet?
|
I meant ClearCommError(), sorry.
| Quote: | I tested the respond time of the embeded unit using Hyperterminal
and it never fails ( < 1ms) you can't even time it, if all your using is
Hyperterminal, just see that it always respond immediately.
|
Then that suggests your code really is not set up properly, if it is taking
up to 10 seconds to get that response. I am still of the opinion that you
need to get rid of ClearCommError() altogether, for the purpose of polling
thequeue status anyway. If the code still runs slowly after removing it,
then something else is still messed up in your remaining code. My guess
would be that either 1) you did not actually configure the baud rate
correctly in your code, or 2) you did not set up the timeouts properly when
you opened the serial port. But I cannot say for sure, because you never
showed any of that code yet.
| Quote: | I don't understand why? Everything tells me the byte should be there
and maybe it is, but definetly I am doing something terribly wrong in
my Read snippet, because I am not getting that byte????
|
You are not using overlaped I/O properly to begin with, because you are
relying on your queue status and not the overlapped status. For that
matter, since your code is processing in a serialized manner anyway, your
Read() method can't return until the reading actually finsihes, so why are
you using overlapped I/O at all? It is not gaining you anythig in this
situation, so you could just remove it altogether and let ReadFile() operate
synchronously instead.
Gambit
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|