[POLL (Open)] Blocking behaviour of Serial.USB during TX

Post here first, or if you can't find a relevant section!

Should SerialUSB.write() block when the host is slow to process data?

Poll ended at Tue Sep 19, 2017 4:37 pm

It should block indefinitely to guarantee delivery to the application.
1
6%
It should not block and return inmediately if there is no space in the buffer (return value indicates number of bytes queued for TX).
5
28%
It should block only for a set timeout period (return value indicates number of bytes queued for TX).
0
No votes
It should block only for a timeout period that matches the baud rate set on SerialUSB.Begin(bauds) (return value indicates number of bytes queue for TX).
4
22%
Configurable at runtime (blocking or non-blocking with small timeout)
7
39%
Other (please explain in a post)
1
6%
 
Total votes: 18

aster
Posts: 110
Joined: Thu Mar 30, 2017 2:41 pm
Location: bella italy
Contact:

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by aster » Fri Sep 01, 2017 10:04 pm

maybe:
Configurable at runtime (blocking or non-blocking with small timeout)
+
if not set at runtime use a default configuration like: It should not block and return inmediately if there is no space in the buffer (return value indicates number of bytes queued for TX).

victor_pv
Posts: 1750
Joined: Mon Apr 27, 2015 12:12 pm

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by victor_pv » Sat Sep 02, 2017 3:04 pm

Looks like so far is going in the direction of having a runtime option to make it block or not block, the return value should match the number of bytes successfully queue, and when non-blocking mode either return inmediately, or with a short timeout depending on speed requested.

Any more votes or different opinions on the expected behaviour?

fpiSTM
Posts: 251
Joined: Fri Sep 16, 2016 12:33 pm
Location: Le Mans, France

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by fpiSTM » Sat Sep 09, 2017 12:57 pm

In fact, I ask myself the same question on the USB behaviour for the STM core.
So, I have the same trouble than you and wait the end of the poll :mrgreen:

victor_pv
Posts: 1750
Joined: Mon Apr 27, 2015 12:12 pm

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by victor_pv » Mon Sep 11, 2017 1:14 am

From everyone's comments so far, and the poll, I think the best expected behaviour is:

-If USB is disconnected, just drop and return with no timeout, and not saving to buffer either. Return indicates 0 bytes were sent. This is how Arduino DUE works.
-If USB is connected, 2 possibly outcomes:
  • by default try to queue to the buffer, and wait for a timeout period. Such timeout simulating the rate at which the port was opened (115200 if nothing was provided). If the bytes can't be sent at that pace, return indicating how many were queued. If the sketch cares to check the return fine, if not, then data is just lost. This is more or less how a USART port would work. If puts the data in the output line, but doesn't care if anyone listen.
  • At runtime you can set the timeout to max (let's say 0xFFFF), or bps rate to 0, and if so, the sending function will block indefinitely waiting until it can send the data. I think that still if the port gets disconnected from the host after the sketch is running, the TX function should just return, dont see a need to block in this case unless someone can explain it to me.


Does that fit everyone needs?

stevestrong
Posts: 1837
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by stevestrong » Mon Sep 11, 2017 8:29 am

Victor, I would not use timeouts at all, just return the nr of bytes successfully sent, because if systick is not used, then the timeout won't work.

danieleff
Posts: 336
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by danieleff » Mon Sep 11, 2017 8:47 am

victor_pv wrote:
Mon Sep 11, 2017 1:14 am
Does that fit everyone needs?
I am ok with that.

BTW my experiments with windows10/usbser.sys driver show that it has a 16K buffer. So if the host PC program opens the COM port, but does not read anything at all, the STM32 USB will be able to send 16K data instantly anyway, bypassing your device timeout.

victor_pv
Posts: 1750
Joined: Mon Apr 27, 2015 12:12 pm

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by victor_pv » Mon Sep 11, 2017 1:48 pm

stevestrong wrote:
Mon Sep 11, 2017 8:29 am
Victor, I would not use timeouts at all, just return the nr of bytes successfully sent, because if systick is not used, then the timeout won't work.
The possible problem with that is if you do a lot of Serial.print in a row, filling up the buffer. I don't think anyone checks return values when they are trying to print information, but at the same time they expect that to be sent, and not lose a line here or there.
As I said if we allow to change it at runtime, we can make it that if timeout is 0, it doesn't even look at systick, just runs once trying to send the data and return what's successfull. That would allow for not using systick.

Let's try to agree on how to manage the possibilities. I suggest using begin() since it's already there. Imagine the following case (and add or modify to it until we all like it).

Code: Select all

Serial.begin(); //No timeout, and no blocking. No guarantee of delivery. We can include some repeat loop in case the sketch is sending data at very fast pace. currently this results in a set timeout of 50ms in the libmaple F1.

Serial.begin(115200); // Use a timeout to approximate 115200 speed.

Serial.begin(0); // Block until it can write data to buffer (no timeout, just blocking), except if the port is totally disconnected (which you should have checked for with !Serial)
Does that seem like an interface easy enough to use and covering most use needs?
If you were using a usart port, the second line would match what the usart code does more or less. If you transplant code from usart, you would not be find begin(0), so it has to be purposely used.
And using just begin() results in sending as fast as possible, but no garantees, like now, but eliminating the timeout all together.

If you use it in a situation where you want to get the data sent or just stop the program, because your use case requires that, you can use begin(0). If you want to try to send but you know your computer software is slow begin(19200), and if you want to try to send, but is debugging information or whatever else that you dont want to affect program flow, then use it as today begin().

fredbox
Posts: 95
Joined: Tue Jul 07, 2015 4:44 pm

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by fredbox » Mon Sep 11, 2017 4:04 pm

-If USB is disconnected, just drop and return with no timeout, and not saving to buffer either. Return indicates 0 bytes were sent. This is how Arduino DUE works.
+1

stevestrong
Posts: 1837
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by stevestrong » Mon Sep 11, 2017 4:09 pm

Just a dummy idea: what about
Serial.begin(<baudrate>, bool blocking = 1 or 0); // 0 per default
basically use second parameter to specify the blocking/non-blocking option.

BTW, libmaple F4 USB serial has these 2 functions:

Code: Select all

void usbEnableBlockingTx(void);
void usbDisableBlockingTx(void);

User avatar
martinayotte
Posts: 1229
Joined: Mon Apr 27, 2015 1:45 pm

Re: [POLL (Open)] Blocking behaviour of Serial.USB during TX

Post by martinayotte » Mon Sep 11, 2017 4:11 pm

Right !
That is what I've said in the other thread several weeks ago.
usbEnableBlockingTx() could have a new argument for the timeout value, and 0 or -1 can indicate blocking forever...

Post Reply