Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeout for RX and TX on ISerialIOStream #23

Open
xamix opened this issue Jun 30, 2017 · 9 comments
Open

Timeout for RX and TX on ISerialIOStream #23

xamix opened this issue Jun 30, 2017 · 9 comments

Comments

@xamix
Copy link

xamix commented Jun 30, 2017

Hello,
I settled your lib which seem to works (I can transmit and receive in BLOCKING mode) I'm currently on Windows but project will need to work on Linux Desktop and Windows.

I wanted to add timeout for the receive parts, so it seem I need to use NONBLOCKING mode:

_outputStream = (SerialComOutByteStream) _serial.getIOStreamInstance(SerialComManager.OutputStream, _handle, SMODE.NONBLOCKING);
_inputStream = (SerialComInByteStream) _serial.getIOStreamInstance(SerialComManager.InputStream, _handle, SMODE.NONBLOCKING);

Now I'm stuck because I cannot find a place where I can set the Timeout for RX parts.
I saw the following function:

fineTuneReadBehaviour(long handle, int vmin, int vtime, int rit, int rttm, int rttc)

But I don't know how to use it. What are the parameters values. I need for example 3000ms of read timeout.
Also I need to differenciate a timeout exception from an error on the stream (ie: if read function on byteStream return -1 for error on stream, what is returned when it timeout? An exception?).

Any help or answer will be appreciated :-)

Regards.

@RishiGupta12
Copy link
Owner

  1. This folder has all examples https://github.com/RishiGupta12/SerialPundit/tree/master/applications
    For API fineTuneReadBehaviour() example is https://github.com/RishiGupta12/SerialPundit/blob/master/applications/d1-timeout-read-com/src/readtimeout/TimeoutReadCallApp.java

  2. Please read the javadoc for fineTuneReadBehaviour() method. Last 3 parameters are applicable for windows and 1st two are used for linux/mac.

  3. If read returns and no data is read this means timeout occurred otherwise read will not return. If error occurs appropriate exception will be thrown which you need to catch in try-catch block.

@xamix
Copy link
Author

xamix commented Jul 3, 2017

Hello, thank you for your answer.
I missed the JavaDoc parts, my apologies.

So I came to the Windows doc here:
https://msdn.microsoft.com/fr-fr/library/windows/desktop/aa363190(v=vs.85).aspx

And in the Remark parts it say:

Remarks

If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than zero and less than MAXDWORD, one of the following occurs when the ReadFile function is called:
If there are any bytes in the input buffer, ReadFile returns immediately with the bytes in the buffer.
If there are no bytes in the input buffer, ReadFile waits until a byte arrives and then returns immediately.
If no bytes arrive within the time specified by ReadTotalTimeoutConstant, ReadFile times out.

So it seem that it's what I'm looking for get a simple read timeout.
I tried to set the timeout like this (with the two parameters equal to MAXDWORD (0xffffffff)):

_serial.fineTuneReadBehaviour(_handle, 0, 0, 0xffffffff, 0xffffffff, 3000);

But it's not possible since it's a negative number with int parameter type and so the function fire an exception.

I tried with Integer.MAX_VALUE, it seem to work but by reading the documentation, it imply multiplyer depending on number of byte to read which is not what I want...

So is there any solution to use the MAXDWORD in your function?

PS: In your example of function for Windows you says that's it's for 500ms tiemout:

            // Tune read method behaviour (500 milliseconds wait timeout value)
            if(osType == SerialComPlatform.OS_WINDOWS) {
                scm.fineTuneReadBehaviour(handle, 0, 0, 0, 0 , 0);

How is it possible with all parameters to 0?

Regards

@RishiGupta12
Copy link
Owner

A quick thought, try this:
fineTuneReadBehaviour(_handle, 0, 0, 3000, 0, 0);

Ignore that all 0 code, it was under development. I will update.

@xamix
Copy link
Author

xamix commented Jul 6, 2017

I cannot say if this works for the moment but reading the documentation involve that this set the ReadTotalTimeoutMultiplier and so:

ReadTotalTimeoutConstant: A constant used to calculate the total time-out period for read operations, in milliseconds. For each read operation, this value is added to the product of the ReadTotalTimeoutMultiplier member and the requested number of bytes.

So it seem not what I expect.

Also I always have problem to determine if a timeout occur:
You say :

If read returns and no data is read this means timeout occurred otherwise read will not return. If error occurs appropriate exception will be thrown which you need to catch in try-catch block.

So what if I read on the _inputStream with:

int res = _inputStream.read(); if (res == -1) throw new EOSException();

If it return -1, End of stream occured, but how to detect timeout on this case? How to know that no byte was read because of timeout and not because the port was closed?

Regards

@xamix
Copy link
Author

xamix commented Jul 6, 2017

Another issue appear:

Very often I get the following exception

java.io.IOException: Unknown error occured in native layer !
	at com.serialpundit.serial.SerialComInByteStream.read(SerialComInByteStream.java:287)

This occur only when receiving byte in serial port and the function fineTuneReadBehaviour was previously called on the port.

If I don't call fineTuneReadBehaviour after opening the port, then this error seem to not occur.

Also it seem that on Windows RX timeout is not working since read with a tab never reurn 0.

@RishiGupta12
Copy link
Owner

There are two goals. One timed read and second port close. Configure finetuneread as mentioned and use non blocking mode when creating stream. This will address goal one. For second goal you will need hardware and driver support. So first we close item one then move to item two.

@xamix
Copy link
Author

xamix commented Jul 11, 2017

Hi!

The timeout with fineTuneReadBehaviour on Linux is working, but on Windows it seem to not works properly, I tryed with many parameters:

fineTuneReadBehaviour(_handle, 0, 0, 3000, 0, 0);
or
fineTuneReadBehaviour(_handle, 0, 0, 0, 0, 3000);
...
without any success. The time seem to be about 1second instead of my 3seconds.

@RishiGupta12
Copy link
Owner

  • How do you know that timeout was 1 second.
  • Is this 1 second always consistent.
  • Use only fineTuneReadBehaviour(_handle, 0, 0, 3000, 0, 0); We need 3rd parameter mainly which says that time interval between the arrival of next byte should not be greater than 3000 milliseconds.
  • Which hardware you are using.

@RishiGupta12
Copy link
Owner

I have also updated example application for timed read TimeoutReadCallApp.java
May you please run this example and share results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants