PORTS Forum
Ports and Interfaces => USB => Topic started by: mediumrare on May 09, 2012, 06:40:23 pm
-
Hello,
I am writing an app that will transfer data (up to 3GBytes filesize) from a linux embedded device over USB to the PC. (C# .NET)
My data transfer rates are much lower than the usb 2.0 specification.
From what I can ascertain doing speed tests with console applications(open device, read while there is something in the pipe), the libusb transfer rate is ~10 times faster than winusb, though that is still only 1MByte/second.
Does anybody know of any documentation on transfer rates using these libraries.
The libusb seems to be transferring about 2048Bytes/ms whereas winusb seems to have an ~11ms between every second packet -see logging extract
nr = 2048 10:35:52.975
nr = 2048 10:35:52.987
nr = 2048 10:35:52.988
nr = 2048 10:35:52.999
nr = 2048 10:35:52.999
nr = 2048 10:35:53.010
nr = 2048 10:35:53.011
nr = 2048 10:35:53.021
At the linux end I am just doing a hexdump of the file out the usb port.
Can anyone shed any light on why this is so - what might the delay be and why don't I see this with libusb?
Thank you to any respondants in advance.
Regards
-
Test it with much greater transfer size, more than mega bytes.
PC host controller delays transfer completion interrupt until next SOF of micro-frame. In this way, the next transfer always starts at next micro-frame, when your PC application repeats transfers synchronously. That is, the transfer speed is proportional to the transfer size, until it saturates the bus bandwidth.
whereas winusb seems to have an ~11ms between every second packet
Sound like you are seeing thread switch quantum, instead of transfer speed.
Is it synchronous (non-OVERLAPPED) call?
For WinUSB, apply RAW_IO policy to the bulk IN pipe. And put a couple of OVERLAPPED WinUsb_ReadPipe calls in advance. And then, these calls are stored on the host controller queue, directly, which results in seamless transfer sequence.
Tsuneo
-
Thank you.
I have tried to make the application as thread-free as possible. Here is my code:
class Program
{
public static USBInterface ifc;
public const string deviceGuid = "8A99B4FA-4942-4286-B464-3D92EF91D0AC";
public bool opened = false;
const int UsbReadBufferSize = 8192;
public static void Main(string[] args)
{
if (ifc != null) throw new InvalidOperationException("Already open");
USBDeviceInfo[] devices = USBDevice.GetDevices(deviceGuid);
USBDevice device = null;
bool firstTimeIn = true;
if (devices.Length > 0)
{
Console.WriteLine("Found device");
device = new USBDevice(devices[0].DevicePath);
ifc = device.Interfaces[1];
ifc.InPipe.Policy.RawIO = true;
}
else
{
Console.WriteLine("No devices found");
}
byte[] buffer = new byte[UsbReadBufferSize];
int nread;
while (ifc != null)
{
//nread = ifc.InPipe.Read(buffer, 0, UsbReadBufferSize);
nread = ifc.InPipe.Read(buffer);
Console.WriteLine("nr = " + nread.ToString() + " " + DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture));
if (nread > 0)
{
if (firstTimeIn)
{
Console.WriteLine("Start=" + DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture));
firstTimeIn = false;
}
if (nread == 2)
{
Console.WriteLine("Finish=" + DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture));
firstTimeIn = true;
}
}
}
}
}
I am not even copying the data from the buffer. Whether or not I put DateTime out every read or not makes no difference to the transfer rate. The last packet is 2 bytes long. I have added your suggestion regarding RAW_IO. However I don't understand what you are suggesting about adding OVERLAPPED ReadPipe calls in advance.... Could you explain this a bit more please?
Thank you
-
DateTime have the resolution of just quantum tick.
Use System.Diagnostics.Stopwatch Class, which applies QueryPerformanceCounter() internally.
Enclose the target routine call with StopWatch.Start and StopWatch.Stop
StopWatch.Elapsed gives the time between Start/Stop
Stopwatch stopWatch = new Stopwatch();
while (ifc != null)
{
stopWatch.Start();
nread = ifc.InPipe.Read(buffer);
stopWatch.Stop();
Console.WriteLine( stopWatch.Elapsed.TotalMilliseconds );
...
Tsuneo
-
Thank you for this suggestion - but I have already tried the stopwatch. I tried it again with your exact suggestion and elapsed time was 16003.7622 for a 2.9MB file.
What are the overlapped read calls you suggested?
Also I know you stated that the bigger the filesize->the faster the transfer rate, but even considering this the above transfer rate is very low for what is these days a very small file.
-
It emerges that the linux command hexdump was the bottleneck, not the usb drivers. Thank you for all your help.