All Forums
 Microsoft Windows CE
 CE Sample Applications and Utilities
 Serial port ReadFile very slow or hang
 Forum Locked
 Send Topic to a Friend
 Printer Friendly
Author Topic  

wabtec4

59 Posts

Posted - 19 May 2005 :  05:15:16  Show Profile  Email Poster
Hello Gurus,
I have a program using ReadFile to read serial ports of Bitsy board with Windows Ce 4.12 installed, the problem is 2 of the ports are responding very slow, in some cases I can read only one byte per second, some times it simply hang up without timing out after reading part of a sent in string, I have configured the ports differently, but the result was the same: very slow or hang up.

After my program reading the serial port for some time, the system becomes very slow.

We have heaps of Bitsy board, our customer want to use the current hardware with CE 4.1, we urgently need you help.
Thansk,

akidder

1519 Posts

Posted - 19 May 2005 :  16:25:13  Show Profile  Email Poster
Thanks. Do you see this behavior when using COMTERM? That would help us sort out if we have to look at the application or the drivers.

Also, can you let us know which ports you're reading and what kind of baud rate and data volume is coming in?
Go to Top of Page

wabtec4

59 Posts

Posted - 19 May 2005 :  19:06:03  Show Profile  Email Poster
Thanks, in our test cases, we set baudrate to 19.2k & 57.6k, timeout values inclusively between MAXDWORD & 0, the data volume was not much, just a few hundreds bytes at this stage, will be MBs later.
We used 3 ports: COM1, COM2, COM3, COM3 seems OK, but COM1 & COM2 are really slow, when COM1 & COM2 begin to work, COM3 eventually becomes very slow.

Do any other people use Bitsyboard with Wince 4.12?
I will have a look at COMTERM, & feed back.
Go to Top of Page

wabtec4

59 Posts

Posted - 19 May 2005 :  19:08:50  Show Profile  Email Poster
We have mutiple threads running, 3 of them are charging the 3 serial ports individually.COM2 & COM3 ocassionally responds a little better.

Go to Top of Page

wabtec4

59 Posts

Posted - 20 May 2005 :  05:39:36  Show Profile  Email Poster
We used COMTERM to test COM1 & COM2 individually, they seemed fast enough, but once we linked the 3 ports, they become very slow, I ever noticed in COM2, we could received only 1 byte per second, or sent 1 byte every 500 minisecond etc, COM1 is the same.
I post my code below:
Go to Top of Page

wabtec4

59 Posts

Posted - 20 May 2005 :  05:49:32  Show Profile  Email Poster

DWORD WINAPI MCDLThreadFunc( LPVOID lpParam )
{
while( true )
{
//1: read MCDLPORT & write ERMPORT till times out
while( (ReadFile( hCOMPort[MCDLPORT], &ch, 1, &ReadNum, NULL )) && (ReadNum > 0) )
{
//we found some bytes from MCDL, send to ERM
WriteFile( hCOMPort[ERMPORT], &ch, 1, &WriteNum, NULL );
}

// 2: read ERM's response & feed back to MCDL till times out
while( ReadFile( hCOMPort[ERMPORT], &ch, 1, &ReadNum, NULL ) && (ReadNum > 0) )
{
WriteOK = WriteFile( hCOMPort[MCDLPORT], &ch, ReadNum, &WriteNum, NULL );
}
} return 0;
}
Go to Top of Page

wabtec4

59 Posts

Posted - 20 May 2005 :  05:51:41  Show Profile  Email Poster
All the 3 ports configuration ( time out values ) are the same as COMTERM configued in your source. I also tried different configures including extreme values.
Thanks,
Go to Top of Page

akidder

1519 Posts

Posted - 20 May 2005 :  07:51:29  Show Profile  Email Poster
Thanks for the details and code snips. Two observations that might help.

One is that your processing loop is running full tilt and isn't yielding to other threads. In a multithreaded environment like CE, you should always insert a yield command. Try putting a Sleep(0) inside your while loops. Alternatively, you could do something like wating for a comm event.

Second, and probably less important, you could also read larger blocks of data from the serial buffers, rather than a byte at a time.

Of these, the first is most important.
Go to Top of Page

wabtec4

59 Posts

Posted - 22 May 2005 :  19:49:50  Show Profile  Email Poster
But the time slice is assigned by operating system other than the programmers.
I ever used WaitForCommEvent() function.
Go to Top of Page

akidder

1519 Posts

Posted - 23 May 2005 :  08:05:03  Show Profile  Email Poster
Without seeing the rest of your code, I can't comment if you have taken steps to set priority levels differently for the various threads. It is standard practice to include a yield statement in each thread of a multi-threaded app.

Please try the suggestion of inserting Sleep(0) in your code to see if it resolves the slowdowns you're seeing.

Using WaitCommEvent is a much more efficient way to handle serial communications, as the thread doesn't do any more processing until the character is received. (I'd have to look at the driver code to see if a ReadFile call polls for characters, or if it uses WaitCommEvent itself.) See this MSDN link for details about using the function. I believe our COMTERM serial demonstration app uses WaitCommEvent() (and also performs a serial relay function like you're using).

For now, I believe the Sleep call will be a quick first test.
Go to Top of Page

akidder

1519 Posts

Posted - 27 May 2005 :  11:38:31  Show Profile  Email Poster
Here is a Microsoft article with some details about how the CE thread scheduler works:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcemain4/html/_wcesdk_scheduling_a_thread.asp


Note that the scheduler will cut off a thread after a period of time if the thread hasn't relinquished control. That time can be 100ms if you haven't used CeSetThreadQuantum().

Use CeSetThreadPriority() and Sleep() or Waitxxx() functions judiciously to get the cooperative behavior you expect from the treads in your app.
Go to Top of Page

wabtec4

59 Posts

Posted - 29 May 2005 :  19:18:04  Show Profile  Email Poster
Thanks, I tried Sleep( 1 ), I couldn't tell what effect it caused. Because I got some new problems:

  COMMTIMEOUTS t = {MAXDWORD,0,0,10,1000};

DWORD ReadTotal = 0;
while( (ReadFile( hCOMPort[MCDLPORT], &ch, 1, &ReadNum, NULL )) && (ReadNum > 0) )
{
//we found some bytes from MCDL, send to ERM
Sleep( 1 );
WriteFile( hCOMPort[ERMPORT], &ch, 1, &WriteNum, NULL );
ReadTotal++;
}


In the above loop, the ReadTotal seemed quite random, for example, the other side sent 120 bytes ( very sure, I could see from COMWATCH ), but the above loop exited with ReadTotal 10, 20, 100 etc, WHat's the problem that I couldn't read the whole 130 bytes?

---------------------------------------------------------------------------------------------
Question 2:
  COMMTIMEOUTS t = {0,0,0,10,1000};

for( int i = 0; i < 4099; i++ )
{
ReadFile( hCOM, &ch, 1, NULL, NULL );
}

I can clearly see the other side sent 4099 bytes, this loop can give me 4099 bytes some times, but very often, ReadFile hang after it read a few hundreds bytes, why?

-------------------------------------------------------------------------------------------------------------
Question 3:
  COMMTIMEOUTS t = {MAXDWORD,0,0,10,1000};

I noticed that for the 1st element, using MAXDWORD ReadFile returns immediately, but using any other values, say 0, 10, MAXDWORD-10, ReadFile waits forever if no data available, why?

Thanks.
Go to Top of Page

wabtec4

59 Posts

Posted - 02 Jun 2005 :  01:59:49  Show Profile  Email Poster
How big are the buffers for serial port input & output? How fast can the serial ports response to pouring in data? I mean the other side is sending to Bitsyboard very fast, but my ReadFile hang after reading for a while.
Go to Top of Page

wabtec4

59 Posts

Posted - 02 Jun 2005 :  05:39:57  Show Profile  Email Poster
for example, in the loop:

for( int i = 0; i < DownloadSize; i++ )
{
WriteFile( hComm, "XX", 2, NULL, NULL );
Sleep( 1 );
Read4099Bytes();
}

The above loop can run sometimes 200 times, some times less than 100 times etc,then it hang up, but my DownloadSize is 520, why?
I can clearly see the other side sent all required data - 4099 bytes within 800 miniseconds.
Yell for help, please ignore the previous 3 questions for the moment.

Below is my Read4099Bytes function.

void Read4099Bytes()
{
char ch = 0;
DWORD ReadNum = 0;
DWORD Total = 0;
while( true)
{
ReadFile( hComm, &ch,1, &ReadNum, 0 );
if( ReadNum > 0 )
{
Total++;
}
if( Total >= 4099 )
{
break;
}
}

Config:COMMTIMEOUTS t = {MAXDWORD,0,0,10,1000};


Go to Top of Page

akidder

1519 Posts

Posted - 02 Jun 2005 :  10:45:58  Show Profile  Email Poster
Thanks for your messages. I think that there are both logic errors and some gaps in understanding about CE that may be getting in the way of you getting a well-functioning application.

Please email us directly and we'll hook you up with the resources you need to get this project completed.
Go to Top of Page

wabtec4

59 Posts

Posted - 03 Jun 2005 :  04:38:36  Show Profile  Email Poster
email sent as above link. Looking forward your reply.
Go to Top of Page
  Topic  
 Forum Locked
 Send Topic to a Friend
 Printer Friendly
Jump To:
Eurotech Support Forums © Eurotech Inc. Go To Top Of Page
This page was generated in 0.05 seconds. Snitz Forums 2000