QFE2 : SerialPort timeout behaviour /should be a bug (.NET MF 4.2 RTM (QFE2))

Dear Sirs,

I have upgraded to latest QFE2 (.NET MF 4.2 RTM QFE2 + GHI NETMF v4.1 v4.2 and .NET Gadgeteer Package (RC2 8-24-2012).zip) to get fix the existing SerialPort.Read() timeout problem exsist in QFE1.

(background info: https://netmf.codeplex.com/workitem/1633 )

Please, correct me what should be the correct behaviour of SerialPort.Read (), timeout, available bytes, number of bytes what I actually try to read system in QFE2?

E.g. based on my opinion:
(datas for case study 1.: timeout=5000 ms, actually received bytes in puffer = 20, number of bytes what I want to read: count = 100 in serialPort.Read( buffer, 0, count ) )

When the serialPort _DataReceived() event fired, I use the int numberOfReallyReaded = serialPort.Read( buffer, 0, count ) it must be a blocking function till
I receive the needed number of bytes (according count e.g. 100)
or
till timeout time is not ellapsed (e.g. 5000 ms).

Let me emphasize I sent only 20 bytes to device serialport puffer in my tests intentionally to force the system to wait (block at Read() function) for 5000 ms timeout.
Another say, I used count = 100 intentionally but it will never should happen (never will be 100 bytes in puffer) as I sent only 20 bytes from 3rd party system.
So based on my opinion SerialPort must wait for timeout period (blocking Read() function), and after timeout period it must go to the next program line.

My problem is: serialPort / Read() function in QFE2:
-quit immediately (never wait for timeout if the actual number of bytes in puffer less than count -what number of bytes I want to read)
-neither never drop exception (if number of bytes in puffer less than the count and the timeout ellapsed).

Is there anybody who can explain: how the serialport should work in a quality mode in QFE2?

thanks !
Péter

I have’t used this myself but the guys here telling me that something changes in timeout that broke a lot of the code we have! We have been to busy with G120 keeping us away from investigating this but it would be great if other ran a quick test to help you/us/netmf.

Dear GUS,

1., I did my home-work (actually with FEZ Hydra) :slight_smile:

:

my test results:
QFE1: Read() function timeout behaviour: works semi-correctly
(wait for timeout period if count (number of bytes what you would like to read) is more than the number of bytes in serial read puffer).
The problem was in QFE1: not exception thrown.

QFE2: never wait for timeout period if number of bytes what you would like to read is more than number of bytes in puffer.
Read function quit immediately.
In this case you have to comparing the return value of Read function with number of bytes you expect to read and do a lot of surplus logic / some extra work to handle these situations.
But it’s funny / not a normal way of working of serialPort in event driven way (serialPort _DataReceived() event fired ).

First I would like to know what is the expected behaviour of serialport in micro framework enviroment? -if it is working correctly.
After that: I’m afraid we have to wait for next release / bug-fix of that, or a workaround at least.

2., Just for information : we ordered some G120HDR (as a RealPress Ltd) a few days ago.
So, it means : I’m ready to do my next home-work / tests with serialport behaviour of G120HDR when it will be arrived.

Waiting for some serial-port GURU who can help in the meantime.
Péter

In the datarecieved event scenario, I don’t understand why you would want to use a buffer larger than the BytesToRead property, and why the timeout would be relevant.

You know you have data, there is no need to have a timeout. You know how many bytes are ready, you don’t need to try to read more than that. Just read the number of bytes that are actually there, exit your event, and move on.

You’d want to use a buffer bigger than the BytesToRead property so that you didn’t have to allocate a new buffer every time you went to read data (which is disastrous from a GC perspective).

If the DataReceived event is raised, and more data comes in between when the event was posted and when you went to read from the port, would the DataReceived even be raised again immediately?

If you read everything available each time the event was raised, fewer events would be raised, leading to faster performance overall, I would think.

Untested hypotesis.

If you start the handler and there’s 10 bytes in the queue based on BytesToRead, then sleep for a second, when 20 more bytes come in, then check BytesToRead I expect you’ll se 30. You read all 30 bytes and then bail from the handler.

Yes, you will most likely have a bigger buffer somewhere, that handles the input. But the original post here talks about trying to read 100 bytes when the BytesToRead is much less; I say why bother, just read what is there and exit. If you are relying on the timeout, you shouldn’t be trying to use it in the datarecieved handler. I think the testing is not going to be useful when using a datarecieved handler - if the same behaviour occurs in a simple read loop, that will point back to a behavioural issue/bug

“Brett King with 28,713 exp 9 hours ago #4
In the datarecieved event scenario, I don’t understand why you would want to use a buffer larger than the BytesToRead property, and why the timeout would be relevant.”

In real life the opposite of it the truth: tipically in datarecieved event scenario you wait for e.g. 100 bytes (becaufe of e.g. the specification of 3rd party system certain command/reply definitions), but datarecieved event triggered at e.g. BytesInBuffer= 1 or 8 or X (you have no control about it). This is why you need timeout parameters: to fill up the serial internal puffer.

(my original test if for to check how the timeout working)

This is the problem / the current situation with QFE2 serialport Read() and timeout behaviour:
This is a duplicate message of my petersesztak wrote Today at 2:56 AM
https://netmf.codeplex.com/workitem/1633

Dear Lorenzte,

First of all thank for your quick and kind reply !

Please, review my two following statements:

1/ According this behaviour: timeout property makes no senses (not really usefull). m’I right ?

2/ Based on my personal opinion: what should be the correct way of working of serialport.Read() function:

count : number of bytes what you would like to read
puffer: number of bytes available in serial puffer
buffer: array to store the datas (consuming datas, I mean the normal output of whole story)
bytesReadedReturnValue: return value of Read() function: how many bytes readed by Read() function.

User case A: the count = puffer (when entering in Read function), the Read() function fill up the buffer, return with count, and everything is ok.

User case B ‘good case’ (let me emphasize this is the most tipical situation !): the count > puffer, the Read() function must be wait internally to get more puffer bytes (BytesInBuffer), if more bytes arrive to puffer and fill up the puffer to reach puffer == count before timeout, the Read() function return with bytes expected (blocking till timeout, but if the needed bytes arrived before timeout you get what you want).

User case B ‘bad case’: If count > puffer condition remains at the moment when timeout occurs, the Read() function return bytesReadedReturnValue and the programmers know (as bytesReadedReturnValue < count) that timeout occurs.
Alternatively: the Read() function should thrown an exception (logically it’s the same).

So, to summarize my opinion: the extra service what expected from Read() function wait and try to refresh BytesInBuffer, puffer till timeout. Without it makes little sens the whole timeout function if Read() return immediately if puffer>=1. (wishlist: pls, replace 1 with count :slight_smile:

3., Another idea to make two types of Read() functions:
ReadSync_Blocking() : usefull if somebody working with a known fixed number of bytes query/response situation (for example to pre-programming the parameters of 3rd party communication IC by serial UART)

ReadAsync_nonBlocking(): usefull if response (3rd party write) bytes with variable length (not possible to know what will be to count parameter in advance)

As I feel what is actually implemented is a something between Sync and Async read function.

Thanks for your comment in advance !
Péter

No, I respectfully disagree. The DataRecieved event handler is where you stuff what data is available at any one time into your own buffer. Outside of the event handler you figure out how much data you have and deal with it when you have what you want.

If you need to wait for a pre-defined number of bytes the simpler way is to do a read in a loop and deal with it that way.
.

@ Brett - please, take care about details :slight_smile:

(the question around data received event/Read function/timeout topics)

I think I’m right.