Hi there, a question about synchronization.

My thread enters an infinite loop and polls the serial port countinuously to read bytes. It works fine. Now I would like to avoid a continuous polling.

I would like that my thread enters the infinite loop and

Step_1 - falls asleep until a byte is received on port or a timeout elapses.
Step_2 - call MessageBox to notify if a byte arrived
Step_3 - goto Step_1

What I did is:
I set a Comm mask with SetCommMask passing EV_RXCHAR.

I call CreateEvent with NULL, FALSE, FALSE, NULL parms.

Step_1 - I call WaitForSingleObject passing o.hEvent and 3000 (milliseconds).
Step_2 - read o.InternalHigh member to check if a byte arrived
Step_3 - goto Step_1

The problem is that function waits for 3 seconds in any case, doesn't matter if bytes are received or not, it waits for 3 seconds anyway. I want that the thread exits its wait status as a byte arrives.

Anyone can help? Thank you
Posted on 2004-02-18 09:31:29 by _OuzO_
Sleep mode? Only interrupts can bring processor out of sleep mode
Posted on 2004-02-18 14:02:45 by mrgone
You shall not use WaitForSingleObject - that API waits until the object becomes triggered. Since you event object isn't really associated with the comm in any way, your thread will be sleeping until the timeout. Forget about event objects in this case, use WaitCommEvent instead.

This will probably work just fine for low-bandwidth serial port stuff - no reason to use interrupts or whatever. If you need high-bandwidth serial (or, especially, parallel) stuff, you might have to write a driver and an ISR - and of course do this the prescribed way, rather than hooking the IDT directly.
Posted on 2004-02-18 14:17:32 by f0dder
Why would you need a driver unless you need to hook the interrupt. You contradict yourself without even knowing it.
Posted on 2004-02-18 15:45:39 by mrgone
No I don't :) - you should use the HAL to set up your ISR, not direct hooking of the IDT. At least if you want to play nice and have your code be compatible.
Posted on 2004-02-18 16:34:51 by f0dder
you should use WaitCommEvent i think..
Posted on 2004-02-19 02:52:40 by kamilh
Yes! WaitCommEvent works fine even if it immediately returns before completed so I have to wait for 'o.InternalHigh'. I do

Step_1: invoke WaitCommWvent, hCom, &dwEvtMask, &o
Step_2: while o.InternalHigh != 4 Sleep(100) ; when a byte is received InternalHigh = 4
Step_3: mov o.InternalHigh, 0 ; reset otherwise it is kept signaled
Step_4: goto Step_1

After that my thread awakes because at least one byte is in input port queue. I can receive on port as one single byte as several bytes.
I would like to avoid calling ReadFile with nNumberOfBytesToRead=1 beacause it would read just 1 byte. This way I will call it as many times as many bytes are in the queue.

If I call ReadFile passing 10 as number of bytes to read it will work more efficiently... if 10 or more bytes are waiting. In this
case I fetch 10 bytes a time.
But if less than 10 bytes are waiting in the input queue ReadFile reads nothing! Can I know in advance how many bytes were
received?

Thanks alot!
_OuzO_
Posted on 2004-02-19 07:00:15 by _OuzO_
ClearCommError api ;

COMSTAT.cbInQue will give you number of bytes in receive buffer ..

why not :

a) waitcomm event
b) WaitForSingleObject,
c) if WAIT_TIMEOUT then do-something;goto c
d) getoverlappedresult
e) clearcommerror
f) if cbinque<>0 read
g) goto a

---------------------------------------------

i think you should call cancelio before calling it again if previous one did not completed yet..
Posted on 2004-02-20 04:22:13 by kamilh
Wowwwwwww!!!!!!!

G R E A T ! ! ! ! It works! Thank you very much Kamilh!

_OuzO_
Posted on 2004-02-20 12:04:10 by _OuzO_
Perhaps the COM-related contents of this thread should be written up and added to the FAQ?
Posted on 2004-02-20 12:55:32 by f0dder