Com-port reading (writing) sometimes delayed

Started by
3 comments, last by Floating 17 years, 7 months ago
Hi I am working on an application that communicates with a microcontroller through serial communication. The PC send a request to the microcontroller which responds within 10 ms. When the response has arrived, the PC sends another request and so on. Communication goes back and forth every 10ms. For some reasons, it seems that reading (or maybe sending data off) the com-port gets delayed some times (especially just after boot-up) and my timings are lost. What could be the reason? Thanks
Advertisement
What operating system? Which API? Synchronous or Asynchronous operations?

The usual PC operating systems are not real-time OSs, therefore you really can't know when your thread or process will be awakened by the scheduler, so it's not easy to meet certain timing requirements. You can try setting your process' priority to something higher, and see if it changes anything.

Without knowing a little more info that's all I can think of off the top of my head.
Thanks for your quick reply.

My application runs under Windows XP Embedded with EWF enabled (caching disk accesses to ram). The application is a console application programmed in C++. I use a serial communication class called CSerial from Ramon de Klein. Operation is asynchronous. I perform a write operation followed by a read operation in a callback routine from a multimedia timer. The timer is armed for a one-shot callback and is rearmed appropriately once a reply was obtained from the microcontroller. The multimedia timer has a very good timing, the only bottleneck seems to be the serial port. Can some priority be set for the port?

The delay happens just after boot-up for a few seconds (delay for up to 1 second sometimes), then becomes less frequent. When I run Window mediaplayer the delay becomes much more frequent.

EDIT: before using a multimedia timer for my write/read routine, I used a normal thread with the Sleep instruction. Setting the priority to "TIME_CRITICAL" did not change a lot, I still had similar delays. The problem really seems to be linked to the serial port.
I don't think your problem is the serial port. If I remember correctly, only a single client can have control of the serial port at a time (although more than one client can snoop and view what's being sent and received). Also, the serial port is not something most applications bother with, so, unless you have some specific programs that make use of the serial port open and active when you run your program, it's a safe bet that you're the only one using the serial port.

Maybe I'm not understanding your design, but you write to the serial port and arm your timer for +10ms, then when the timer fires you attempt to read from the serial port, and if successful, write back to the serial port and re-arm the timer for +10ms, repeat. The problem with that is as I said before, you may set your timer for 10ms in the future, and the OS will probably see the timer expire at that time, but that doesn't mean your callback will be called exactly 10ms in the future, it could be later than that, depending on what the scheduler is doing, and by the time you write back to the serial port you'll be late to the microcontroller.

But really, an easier solution exists. You can set a timeout for your read call from the serial port, so the call will return if no data is read in a certain amount of time. Just set your timeout to 10ms and if the microcontroller doesn't respond in that time you'll know, otherwise your read call will return and you can immedialety write back to the serial port and issue another read call. Again, I don't think you can guarantee that after the read call returns your process or thread wont lose the CPU, which might possibly delay you, and running a media player at the same time definitely won't help that. It's probably the same deal a few seconds after boot, the CPU gets bogged down and you get the timer callback late.
Thanks again Outrider for taking the time to answer.

I use the multimedia timer in a little different manner:

1. I arm the timer to fire in x ms
2. When inside the callback (x ms later) I write a request to the serial port and read it directly after (with a timeout of 15 ms)
3. The microcontroller checks the serial port every 10ms. When it got a request, it replies directly with some data
4. The PC receives the data on the serial port and rearms the callback to fire in x ms.
5. we are back at point 2.

Timing is performed by the microcontroller which will respond only once every 10ms. x has to be choosen small enough (now typically 2ms). The multimedia timer isn't making the timing, I just use it because I first thought my timing was bad because of the Sleep I used in my previous routine (which was a thread with PRIORITY_TIME_CRITICAL):

1. I write a request on the serial port
2. I read data on the serial port with a timeout of 15 ms
3. I sleep x ms (x=2)
4. I go to point 1

Both above routines give me bad timings at start-up and when the media player is running for instance. If I skip point 1 and 2 in above routine, my timing is perfect! (+- 1ms perfect). So I concluded the bottleneck is the serial port. Is that reasoning wrong?

Marc

This topic is closed to new replies.

Advertisement