Page 1 of 3

USB FS Maximum Throughput

Posted: Thu Oct 29, 2015 6:30 pm
by jayalfredprufrock
I have been using 4bit SDIO on a STM32F411RE board and have been achieving ~1.2MB/s using FatFS to save over 100MB of sensor data on a SD card. Now I'm looking for ways of getting that data onto a computer without removing the SD card from the board.

I first tried implementing Mass Storage, but was unable to get it working reliably on both OSX and Windows and it was unclear whether that was going to be performant using FS anyways. Next I figured I could just transfer the data using the serial driver, and after increasing the USB serial buffers, I have only been able to achieve ~150KB/s, which is just not fast enough for my purposes. Is this the best I can hope to achieve with FS? I read some older threads and it sounded like I could bypass the queues of the serial driver and use usbPrepareTransmit() and usbStartTransmitI() directly but I am still struggling to get that to work as well. Can anybody comment on the kind of performance improvement I might see by using that technique? I also read that implementing double-buffering in the USB driver might be the only way to improve throughput, but it's unclear if this is something that is still on the horizon for ChibiOS 3. Finally, I've seen the recent discussion about using isochronous USB mode, and while I realize it's not really for bulk data transfer, perhaps there's a way to leverage that functionality somehow?

I guess my questions boil down to this: If I'm looking to achieve > 150KB/s USB transfer, where should I be focusing my efforts? If somebody could confirm they've achieved greater speeds using MSC w/ USB FS (or any method for that matter), I'd consider spending more time getting that method to work. If it's unlikely that I'll ever see anything better than 150KB/s short of implementing double-buffering then I'll just have to deal with the slow speeds (but at least I can move on).

BTW, here is the code I'm using to measure speed.

Code: Select all

   uint16_t i;
   static uint8_t data[SERIAL_USB_BUFFERS_SIZE] = { 0 };
   static time_measurement_t time;
   float speed;

   chTMObjectInit(&time);
   chTMStartMeasurementX(&time);

   //Send 1MB of data, in chunks equal to the usb buffer size
   for (i=0; i < (1024*1024 / SERIAL_USB_BUFFERS_SIZE); i++)
   {
      chSequentialStreamWrite((BaseSequentialStream*)&SDU1, data,  SERIAL_USB_BUFFERS_SIZE);
   }
   
   chTMStopMeasurementX(&time);

   speed = 1024000 * ((float)1 / RTC2MS(STM32_SYSCLK, time.cumulative));

   cliPrintf("USB Transfer Speed: %0.2f KB/s\r\n", speed);

Re: USB FS Maximum Throughput

Posted: Fri Oct 30, 2015 12:57 am
by chibby
What is this port speced as supporting?

From memory I think it is only "full speed" which is USB1.1 speed of 12Mbps aka 1.5MB/s

I have seen several reports that the CDC OTG drivers in the ST CMISS code is slow and unreliable. I don't know whether this applies to the STLINK too. The board that you refer to only has the STLINK.

AFAIK, Chibios relies on the ST code for the low level stuff, so will suffer from any inadequacies at that level.

Re: USB FS Maximum Throughput

Posted: Fri Oct 30, 2015 1:05 am
by jayalfredprufrock
The port is only Full Speed, so you're right that the theoretical limit is 1.5MB/s but of course I'm not seeing anything close to that using the OTGv1 + USB serial driver. I would be satisfied with 500KB/s, so I'm just hoping somebody can point me to a project that has successfully achieved speeds in this range so I can poke around and see if it's possible to speed up my transfer rates somehow.

Re: USB FS Maximum Throughput

Posted: Fri Oct 30, 2015 9:08 am
by flabbergast
My impression is that ChibiOS USB Serial implementation (and the USB driver itself) is not designed to achieve the best possible transfer speeds, but to be general enough to allow for "easy" implementation for different low-level chip-internal modules.

While this doesn't say anything about ChibiOS specifically, the graphs in these benchmarks should be a clear indication that there's usually a huge difference between using "general" drivers and writing a specialised "driver" that talks to the hardware yourself.

That doesn't mean that you wouldn't be able to squeze 500KB/s with the standard ChibiOS USB driver if you get rid of the queues (and maybe other overhead) that's in the ChibiOS example USB Serial example (see the "standard" bars for Teensy 3.0 and Fubarino mini in the above benchmarks).

Re: USB FS Maximum Throughput

Posted: Fri Oct 30, 2015 9:19 am
by Giovanni
Hi,

The driver has been reported to work up to 1.1MB/sec, I am searching the forum about that, there was a lot of talk about this years ago.

About performance:
- Make sure to have large buffers for queues, multiples of packet size.
- There is an "USB pump" thread at low priority, if your application is CPU-intensive then it is going to slow down USB transfers, you may need to reorded priorities.
- Perform large writes on queues, make it so that there is always at least one packet worth of data in them.

I am searching the old threads but a lot of results pops up, try to google: usb speed 1.1 site:forum.chibios.org

About examples, see the USB-CDC demo, the shell command "write" is supposed to transmit at maximum speed.

Giovanni

Re: USB FS Maximum Throughput

Posted: Fri Oct 30, 2015 9:24 am
by Giovanni
chibby wrote:AFAIK, Chibios relies on the ST code for the low level stuff, so will suffer from any inadequacies at that level.


Nope, ChibiOS HAL exists for those that don't want to use vendors code. Only CMSIS headers are used.

Giovanni

Re: USB FS Maximum Throughput

Posted: Fri Oct 30, 2015 5:59 pm
by jayalfredprufrock
Thanks so much Giovanni, I'll do exactly as you say and report back after I've figured things out. I'm already doing most of what you suggest, but I haven't played around with thread priorities much and I do have a lot of background tasks going on.

Re: USB FS Maximum Throughput

Posted: Fri Oct 30, 2015 9:45 pm
by chibby
Nope, ChibiOS HAL exists for those that don't want to use vendors code. Only CMSIS headers are used.


Thanks for the clarification. I'd seen the dependency on CMSIS and thought that it was using their low level code.

Does Chibios implement the full OTG functionality ?

IIRC, these boards provide USB 2.0 "Hi Speed" but only 1.1 "Full speed" in OTG mode. I'll have to check the spec to be sure.

[EDIT]

Here we are: from the datashhet for the chip:

STM32F405xx
STM32F407xx
ARM Cortex-M4 32b MCU+FPU, 210DMIPS, up to 1MB Flash/192+4KB RAM,
USB OTG HS/FS, Ethernet, 17 TIMs, 3 ADCs, 15 comm. interfaces & camera

■Advanced connectivity
––USB 2.0 full-speed device/host/OTG
controller with on-chip PHY
USB 2.0 high-speed/full-speed
device/host/OTG controller with dedicated
DMA, on-chip full-speed PHY and ULPI

USB OTG FS characteristics
The USB OTG interface is USB-IF certified (Full-Speed). This interface is present in both
the USB OTG HS and USB OTG FS controllers.


USB 1:
OTG FS
FS

USB 2
HS
ULPI
OTGFS
FS

Re: USB FS Maximum Throughput

Posted: Sat Oct 31, 2015 3:40 pm
by jscott
Here is a thread where we discussed some usb-cdc speed tests. In my testing I was getting ~900,000 bytes per second or 9mbits.

This was a sustained speed over a period of a couple of minutes or so.

This was using a st32f4-discovery running at 168Mhz. With the processor you have, I don't know if you will reach that point or not.

Included in this post if the code I used to do the testing. You may be able to adapt it to perform more testing on your platform.

http://forum.chibios.org/phpbb/viewtopic.php?f=2&t=920

-John

Re: USB FS Maximum Throughput

Posted: Sat Oct 31, 2015 4:18 pm
by Giovanni
Only USB-device is supported.

Giovanni