What is a realistic data transfer rate for full speed USB?
There are a few things that can get in the way of achieving maximum speed over usb.
While a full speed USB wire is capable of 12Mbps an individual device only has access to a limited set of that bandwidth.
When a bulk transfer is used the maximum rate possible is 8Mbps due to the overhead of USB itself (control transfers and other overhead).
For interrupt transfers (used by HID) each packet is 64 bytes and a device my request an interrupt every 1ms. This gives a maximum throughput of 512Kbps.
In order to achieve the full speed available every packet sent must be full (64Bytes of data). Any empty bytes in a packet will be wasted and reduce the throughput.
lets assume that we are writing an application to transfer data to a device. The user requests 96 Bytes be sent, then requests another 96 bytes be sent. In the simple case our software services the first request by sending out a 64 byte packet and then a 32 byte packet. It then looks at the next request and again sends out a 64 byte packet followed by another 32 byte packet. This means that each 96 byte packet used 128 bytes of band-with. Each 32 byte packet had 32 blank spots. Because of these blank spots instead of 8Mbps we only get 6Mbps.
If the user had made a single 192 byte request or the software had been smart enough to composite the requests then the result would have been 3 full 64 byte transfers and hit the full 8Mbps.
This idea becomes more important as the complexity of the data encoding increases. For example if the MCU is sending some data out SPI and some data out UART compositing that data into packets to make full use of band-with becomes more difficult since the sources of that data may be asynchronous.
The MCU needs to have enough CPU cycles to actually move and process the data. For example if a system is implementing a USB to SPI bridge the firmware will need to service USB (handle interrupts, set status bits etc), copy the data from USB to SPI, and service the SPI block. If firmware is highly optimized then on a 48Mhz CPU it will be able to sustain 8Mbps.
However, some CPU cycles may be needed for more advanced features such as configurable NSS assert timing, supporting multiple SPI slaves, advanced error checking and generation. In this case the CPU may not be fast enough to keep up with 8Mbps of incoming data.
As an example one internal (Silicon Labs) implementation of USB to SPI which supports advanced features was able to achieve 7.5Mbps sustained throughput.
In through put optimized applications that have a single stream of data which can be efficiently packed into 64 byte packets and dedicate the MCU to servicing that data it's reasonable to achieve near 8Mbps throughput.
In applications that are servicing multiple streams of data or where the MCU has to service other things in the system 4-6 Mbps would be more realistic.
If the MCU is doing a lot of computation in addition to servicing USB, or if the underlying protocol forces the use of numerous small packets instead of full packets then performance bay be as low as 1-2 Mbps (or <1Mbps if taken to the extreme).
USBXpress is implemented over a Bulk USB pipe. However, there is some overhead on both the software (PC) and firmware (MCU) side which will degrade performance. The throughput for USBXpress will top out around 6Mbps assuming that CPU Load and Data Pipe Efficiency are not limiting factors.