Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

abort read com if nothing comes 1

Status
Not open for further replies.

Jiko

Technical User
Apr 5, 2002
35
SE
Hello!
I communicate with different modules via com-port.I'm the master and they are slaves. They just answer me then I call them. But if they dont answere me.My program don't want to wait for ever. After a certain time I want to stop reading from the comport.Because in that case I want to send a new command on the comport insted.
How can I do that?
I use a command like this. Waits for 3 Bytes.
ReadFile(hCom, cBuffer, 3, &dwBytesRead, NULL);
But if I don't receiev 3 bytes I get stuck!
Best Regards
Mikael Brolin
 
Hi,

Call the SetCommTimeouts API before you read the port. You can set a timeout with this. After the timeout has expired, ReadFile fails.
Marcel
 
Thanks Marcel!
But I have problem then I Init the struct.
SetCommTimeouts want this parameters:
BOOL SetCommTimeouts(
HANDLE hFile, // handle to comm device
LPCOMMTIMEOUTS lpCommTimeouts // pointer to comm time-out structure
);
lpCommTimeouts = Pointer to a COMMTIMEOUTS structure that contains the new time-out values

typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

I create a pointer to the struct like this in my Dlg.h file:
LPCOMMTIMEOUTS LpCommTimeouts;
In my Dlg.cpp file I try to INIT the different variabels in the struct like this:
LpCommTimeouts->ReadTotalTimeoutMultiplier = 100;
Tried different numbers!
My program fails(abort) then it does this. It don't complane then I compile the program.
Then I write to test timeout:
if (SetCommTimeouts(hCom,LpCommtimeouts) != 0)
ReadFile(hCom, cBuffer, val, &dwBytesRead, NULL);

Can anybody explane this to me??
Thanks!!
Mikael Brolin
 
Mikael,

if you declare a LPCOMMTIMEOUTS, the thing you declare is a POINTER TO a COMMTIMEOUTS structure. This does NOT declare the COMMTIMEOUTS structure. If you want to work with a pointer, you must allocate memory for the structure first.
It is easier to declare a COMMTIMEOUTS structure instead of a pointer.
What you need to do is this:

1. Change the declaration LPCOMMTIMEOUTS lpCommTimeouts; to COMMTIMEOUTS CommTimeouts;
2. Change all lpCommTimeouts->*** to CommTimeouts.***
3. Change the secord argument of the SetCommTimeouts call, lpCommTimeouts to &CommTimeouts
Marcel
 
Thanks Marcel!
It's ok now, BUT now I also want to skip rest of the code in my function then a timeout occurs in COMMTIMEOUTS. SetCommTimeouts returns like this:
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Will SetCommTimeouts return zero then timeout occurs??
I believe so. But I dont get it right!
ex:::
***************************
CommTimeouts.ReadTotalTimeoutMultiplier = 1;//short time
CommTimeouts.ReadTotalTimeoutConstant = 1;
int errorcode = 0;
if (errorcode=SetCommTimeouts(hCom,&CommTimeouts) != 0){
ReadFile(hCom, cBuffer, val, &dwBytesRead, NULL);
}
if (errorcode == 0)
MessageBox("Timeout","",NULL);

UpdateData(FALSE);
MessageBox("error","",NULL);
******************************
Result errorcode = 1.
Also tried with GetLastError() but just get 0 as response.
errorcode =GetLastError();
It says like this about GetLastError:
The return value is the calling thread's last-error code value. Functions set this value by calling the SetLastError function. The Return Value section of each reference page notes the conditions under which the function sets the last-error code.
 
Mikael,

I'm not quite sure what you mean.
The return value of SetCommTimeouts tells you whether the call to SetCommTimeouts did succeed or not. If a timeout occurs, this is NOT reported by SetCommTimeouts, but by a ReadFile call after a succesfull SetCommTimeouts call.

So your code should be something like this:

1. HANDLE hCom = CreateFile ( "COM1", ... );
2. if ( hCom == INVALID_HANDLE_VALUE )
{ // failed to open com-port. com-port in use?
// error recovery or abort program here
}
3. fill the COMMTIMEOUTS structure
4. if ( !SetCommTimeouts ( ... ))
{ // SetCommTimeouts failed
// Probably invalid handle
// it is up to you if you want to continue
}
5. if ( !ReadFile ( hCom, ... ))
{ DWORD Erc = GetLastError ( );
// If a timeout is the cause of the error,
// Erc will most likely be ERROR_COUNTER_TIMEOUT
// (this is error 1121)
// If it is 1121 you can resend your data to the
// other side of the line and try again.
// After a few unsuccessful retries, assume
// the other side of the line has died.
}
Marcel
 
Thank you Marcel!
But I think I'm stupid, because I don't get it right anyway!I've done like this:
*****************************************************
CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
CommTimeouts.ReadTotalTimeoutConstant = 100;
if(!SetCommTimeouts(hCom,&CommTimeouts)){
//just continue
if(!ReadFile(hCom, cBuffer, val, &dwBytesRead, NULL)){
//Inside
DWORD m_Felkod=GetLastError();
UpdateData(FALSE);
MessageBox("error","",NULL);
}
else
MessageBox("setcommtimeouts error","",NULL);
if(m_Felkod == 0){
//continue
***********************************************
If I don't use setcommtimeouts I get stuck in ReadFile and
then I use it I get A return from ReadFile then the timeout occurs. But I want to know that went wrong!

If the function ReadFile succeeds, the return value is nonzero.

If the function ReadFile fails, the return value is zero.

To get extended error information, call GetLastError.


If the return value is nonzero and the number of bytes read is zero, the file pointer was beyond the current end of the file at the time of the read operation. However, if the file was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the return value is FALSE and GetLastError returns ERROR_HANDLE_EOF when the file pointer goes beyond the current end of file.
I have NULL in this flag!(FILE_FLAG_OVERLAPPED)

The result from ReadFile must be 0 in my case and the result from GetLasterror = 1121.
But then I call GetLasterror I just get result = 0.
Witch means no error!
I know for sure that nothing is send from the side on the line, so my setcommtimeouts will expire.
Hope you can explane this to me !!
Thanks Mikael Brolin
 
Mikael,

You're right. Having an unlimited trust in mr. Gates, I did not try this myself. Sorry, but I did try it now. I found that ReadFile succeeds, even when no byte has been read.

But, in spite of the success of ReadFile, you can check the fourth parameter of ReadFile (lpNumberOfBytesRead), which gives you a number less than the number of bytes you wanted to read if a timeout has occurred.

The following program will tell you zero bytes have been read:


Code:
#include <windows.h>
#include <stdio.h>

HANDLE OpenCom ( char *Com )
{
  HANDLE hCom = CreateFile ( Com, GENERIC_READ | GENERIC_WRITE,
                             0, 0, OPEN_EXISTING, 0, 0 );
  if ( hCom == INVALID_HANDLE_VALUE )
     { char Msg[100];
       sprintf ( Msg, &quot;Opening port %s returned error code %d&quot;,
                      Com, GetLastError ( ));
       MessageBox ( NULL, Msg, &quot;OpenCom&quot;, MB_OK | MB_ICONERROR );
       exit ( 0 ); }

  COMMTIMEOUTS cto;

  cto.ReadIntervalTimeout         = 0;
  cto.ReadTotalTimeoutMultiplier  = 1000;
  cto.ReadTotalTimeoutConstant    = 100;
  cto.WriteTotalTimeoutMultiplier = 1000;
  cto.WriteTotalTimeoutConstant   = 100;

  if ( !SetCommTimeouts ( hCom, &cto ))
     { char Msg[100];
       sprintf ( Msg, &quot;Setting timeout on port %s returned error code %d&quot;,
                      Com, GetLastError ( ));
       MessageBox ( NULL, Msg, &quot;SetCommTimeouts&quot;, MB_OK | MB_ICONINFORMATION ); }

  return hCom; }


void main ( )
{
  char Com1[] = &quot;COM1:&quot;;

  HANDLE hCom = OpenCom ( Com1 );

  char ReceivedData[1024];
  DWORD cbBytesRead;

  if ( !ReadFile ( hCom, ReceivedData, 3, &cbBytesRead, NULL ))
     { char Msg[100];
       sprintf ( Msg, &quot;Reading port %s returned error code %d&quot;,
                      Com1, GetLastError ( ));
       MessageBox ( NULL, Msg, &quot;ReadFile&quot;, MB_OK | MB_ICONINFORMATION ); }

  char Msg[100];
  sprintf ( Msg, &quot;%d bytes were read&quot;, cbBytesRead );
  MessageBox ( NULL, Msg, &quot;ReadFile&quot;, MB_OK | MB_ICONINFORMATION );
  CloseHandle ( hCom ); }

Marcel
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top