usb_serial_write question

Status
Not open for further replies.

WMXZ

Well-known member
I have the following observation (is not really a problem yet, but..)

My T3.1, 144MHz overclocked, writes 896 bytes over USB to a PC win8.1.
I use multiple 'usb_serial_write' (each 64 bytes), each followed by 'usb_serial_flush_output'

I have two timings
1) NO PC connection, i.e. no program that reads the data, the time spent to 'upload' data to usb_serial system: 10 us (+-).
OK, this is the time could represent the time required to load the different the data into the usb buffers etc.

2) PC reading data, the T3 time to upload data into usb : 660 us.

Now, while the timings are reasonable, it seems the T3 is blocking CPU while transferring data over usb as 660 us correspond to about 1 Mbit transfer rate (T3 to PC).

Is this correct? Does T3 blocks (or uses) the CPU while transferring data over usb_serial?

If yes, is there any option, to upload data to usb driver and not to wait for transmission?

grazie
Walter
 
2) PC reading data, the T3 time to upload data into usb : 660 us.

Now, while the timings are reasonable, it seems the T3 is blocking CPU while transferring data over usb as 660 us correspond to about 1 Mbit transfer rate (T3 to PC).

Is this correct?

I believe 896 bytes in 660 us works out to be 1.36 MByte/sec, which would be 10.9 Mbit/sec. That's a lot more than 1 Mbit/sec!

It also must be missing some other time your program spends not waiting, because it's faster than the theoretical maximum USB full speed bulk transfer rate, which is 1.216 Mbyte/sec.


Does T3 blocks (or uses) the CPU while transferring data over usb_serial?

The USB stack uses a pool of buffers. If enough buffer space is available to hold your write, the function copies everything into buffer memory and returns very quickly. But if more buffer space is needed, it waits in a busy loop until buffers are available.


If yes, is there any option, to upload data to usb driver and not to wait for transmission?

You can increase the number of buffers. Edit NUM_USB_BUFFERS, here:

https://github.com/PaulStoffregen/cores/blob/master/teensy3/usb_desc.h#L96

However, if your sustained data rate is more than the available USB bandwidth, eventually you'll fill up all the buffers, forcing the code to wait.


Another point to keep in mind is Teensy has no control over the available USB bandwidth. All USB bandwidth is managed by the USB host controller chip in your PC. Different machines, with different hardware and different driver software, and with different sets of USB devices connected, will have different available USB bandwidth. Typically, between 0.9 to 1.1 Mbyte/sec tends to be available on modern PCs, when other USB devices like webcam's aren't active.

But there's no guarantee. That's the nature of USB bulk protocol (which Serial uses). You get all the available bandwidth that the USB host controller chip believes isn't required for other devices. The interrupt and isync transfer modes have different trade-offs, with limited but guaranteed bandwidth. But the entire device doesn't work using those modes, if the USB host controller can't meet the guarantee. Bulk protocol always works, and normally you get a nearly all the USB bandwidth, but it's possible to get a lot less if other devices are using the shared bus.
 
Last edited:
I believe 896 bytes in 660 us works out to be 1.36 MByte/sec, which would be 10.9 Mbit/sec. That's a lot more than 1 Mbit/sec!
Thanks Paul, you are right!
It also must be missing some other time your program spends not waiting, because it's faster than the theoretical maximum USB full speed bulk transfer rate, which is 1.216 Mbyte/sec.
Now this makes more sense. Or at least, 10% CPU load during actual usb-transfer seems plausible.

You can increase the number of buffers. Edit NUM_USB_BUFFERS, here:

https://github.com/PaulStoffregen/cores/blob/master/teensy3/usb_desc.h#L96
Thanks for pointer. I will play with that number.

edit: changing the value made the situation worse (more CPU load during usb transfer). There may be some side-effects. I will keep the value and accept the performance.

However, if your sustained data rate is more than the available USB bandwidth, eventually you'll fill up all the buffers, forcing the code to wait.
The required usb data rate is very low. These 896 bytes are transferred only every 100 ms. The CPU load is, however very high and the local impact of this delay could be significant.

E.g. sampling at 180 kHz, processing every 256 samples, whereby processing needs 1.1 ms (of the 1.4 ms available). For the moment I can recover the 0.6 ms usb-transfer by delayed execution of the subsequent signal processing tasks.
 
Last edited:
Status
Not open for further replies.
Back
Top