private static void SetTestDefaults(BENCHMARK_TEST_PARAM test) { test.Ep = 0x00; test.Vid = 1234; test.Pid = 5678; test.Refresh = 1000; test.Timeout = 5000; test.TestType = BENCHMARK_DEVICE_TEST_TYPE.TestTypeLoop; test.BufferSize = 4096; test.BufferCount = 1; test.Priority = ThreadPriority.Normal; }
private static int Main(string[] argv) { BENCHMARK_TEST_PARAM Test = new BENCHMARK_TEST_PARAM(); BENCHMARK_TRANSFER_PARAM ReadTest = null; BENCHMARK_TRANSFER_PARAM WriteTest = null; if (argv.Length == 0) { ShowHelp(); return -1; } ShowCopyright(); SetTestDefaults(Test); // Load the command line arguments. if (ParseBenchmarkArgs(Test, argv.Length, argv) < 0) return -1; if (Test.UseList) { if (GetTestDeviceFromList(Test) < 0) goto Done; } else { // Open a benchmark device. see Bench_Open(). Test.Device = Bench_Open(Test); } if (Test.Device == null) { CONERR("device {0:X4}:{1:X4} not found!\n", Test.Vid, Test.Pid); goto Done; } // If "NoTestSelect" appears in the command line then don't send the control // messages for selecting the test type. // if (!Test.NoTestSelect) { if (Bench_SetTestType(Test.Device, Test.TestType, Test.Intf) != 1) { CONERR("setting bechmark test type #{0}!\n{1}\n", Test.TestType, UsbDevice.LastErrorString); goto Done; } } CONMSG("Benchmark device {0:X4}:{1:X4} opened..\n", Test.Vid, Test.Pid); // If reading from the device create the read transfer param. This will also create // a thread in a suspended state. // if ((Test.TestType & BENCHMARK_DEVICE_TEST_TYPE.TestTypeRead) != 0) { ReadTest = CreateTransferParam(Test, Test.Ep | 0x80); if (ReadTest == null) goto Done; } // If writing to the device create the write transfer param. This will also create // a thread in a suspended state. // if ((Test.TestType & BENCHMARK_DEVICE_TEST_TYPE.TestTypeWrite) != 0) { WriteTest = CreateTransferParam(Test, Test.Ep); if (WriteTest == null) goto Done; } // If this is a "whole" usb device (libusb-win32, linux libusb-1.0) // it exposes an IUsbDevice interface. If not (WinUSB) the // 'wholeUsbDevice' variable will be null indicating this is // an interface of a device; it does not require or support // configuration and interface selection. IUsbDevice wholeUsbDevice = Test.Device as IUsbDevice; if (!ReferenceEquals(wholeUsbDevice, null)) { // This is a "whole" USB device. Before it can be used, // the desired configuration and interface must be selected. // Select config #1 if (!wholeUsbDevice.SetConfiguration(1)) { CONERR("setting configuration #{0}!\n{1}\n", 1, UsbDevice.LastErrorString); goto Done; } // Claim interface #0. if (!wholeUsbDevice.ClaimInterface(Test.Intf)) { CONERR("claiming interface #{0}!\n{1}\n", Test.Intf, UsbDevice.LastErrorString); goto Done; } } if (Test.Verify) { if (ReadTest != null && WriteTest != null) { if (CreateVerifyBuffer(Test, (ushort) WriteTest.Ep.EndpointInfo.Descriptor.MaxPacketSize) < 0) goto Done; } else if (ReadTest != null) { if (CreateVerifyBuffer(Test, (ushort) ReadTest.Ep.EndpointInfo.Descriptor.MaxPacketSize) < 0) goto Done; } else { // This is a write only test; nothing to do here. } } ShowTestInfo(Test); ShowTransferInfo(ReadTest); ShowTransferInfo(WriteTest); CONMSG0("\nWhile the test is running:\n"); CONMSG0("Press 'Q' to quit\n"); CONMSG0("Press 'T' for test details\n"); CONMSG0("Press 'I' for status information\n"); CONMSG0("Press 'R' to reset averages\n"); CONMSG0("\nPress 'Q' to exit, any other key to begin.."); char key = Console.ReadKey().KeyChar; CONMSG0("\n"); if (key == 'Q' || key == 'q') goto Done; // Set the thread priority and start it. if (ReadTest != null) { ReadTest.ThreadHandle.Priority = Test.Priority; ReadTest.ThreadHandle.Start(ReadTest); } // Set the thread priority and start it. if (WriteTest != null) { WriteTest.ThreadHandle.Priority = Test.Priority; WriteTest.ThreadHandle.Start(WriteTest); } while (!Test.IsCancelled) { Thread.Sleep(Test.Refresh); if (Console.KeyAvailable) { // A key was pressed. key = Console.ReadKey().KeyChar; switch (key) { case 'Q': case 'q': Test.IsUserAborted = true; Test.IsCancelled = true; break; case 'T': case 't': ShowTestInfo(Test); break; case 'I': case 'i': // LOCK the display critical section lock (DisplayCriticalSection) { // Print benchmark test details. ShowTransferInfo(ReadTest); ShowTransferInfo(WriteTest); } break; case 'R': case 'r': // LOCK the display critical section lock (DisplayCriticalSection) { // Reset the running status. ResetRunningStatus(ReadTest); ResetRunningStatus(WriteTest); // UNLOCK the display critical section } break; } // Only one key at a time. while (Console.KeyAvailable) Console.ReadKey(true); } // If the read test should be running and it isn't, cancel the test. if ((ReadTest != null) && !ReadTest.IsRunning) { Test.IsCancelled = true; break; } // If the write test should be running and it isn't, cancel the test. if ((WriteTest != null) && !WriteTest.IsRunning) { Test.IsCancelled = true; break; } // Print benchmark stats if (ReadTest != null) ShowRunningStatus(ReadTest); else ShowRunningStatus(WriteTest); } // Wait for the transfer threads to complete gracefully if it // can be done in 10ms. All of the code from this point to // WaitForTestTransfer() is not required. It is here only to // improve response time when the test is cancelled. // Thread.Sleep(10); // If the thread is still running, abort and reset the endpoint. if ((ReadTest != null) && ReadTest.IsRunning) ReadTest.Ep.Abort(); // If the thread is still running, abort and reset the endpoint. if ((WriteTest != null) && WriteTest.IsRunning) WriteTest.Ep.Abort(); // Small delay incase usb_resetep() was called. Thread.Sleep(10); // WaitForTestTransfer will not return until the thread // has exited. WaitForTestTransfer(ReadTest); WaitForTestTransfer(WriteTest); // Print benchmark detailed stats ShowTestInfo(Test); if (ReadTest != null) ShowTransferInfo(ReadTest); if (WriteTest != null) ShowTransferInfo(WriteTest); Done: if (Test.Device != null) { Test.Device.Close(); Test.Device = null; } FreeTransferParam(ref ReadTest); FreeTransferParam(ref WriteTest); CONMSG0("Press any key to exit.."); Console.ReadKey(); CONMSG0("\n"); UsbDevice.Exit(); return 0; }
private static int ParseBenchmarkArgs(BENCHMARK_TEST_PARAM testParams, int argc, string[] argv) { string arg; string value; int iarg; for (iarg = 0; iarg < argc; iarg++) { arg = argv[iarg].ToLower(); if (GetParamIntValue(arg, "vid=", ref testParams.Vid)) { } else if (GetParamIntValue(arg, "pid=", ref testParams.Pid)) { } else if (GetParamIntValue(arg, "retry=", ref testParams.Retry)) { } else if (GetParamIntValue(arg, "buffercount=", ref testParams.BufferCount)) { if (testParams.BufferCount > 1) testParams.TransferMode = BENCHMARK_TRANSFER_MODE.TRANSFER_MODE_ASYNC; } else if (GetParamIntValue(arg, "buffersize=", ref testParams.BufferSize)) { } else if (GetParamIntValue(arg, "size=", ref testParams.BufferSize)) { } else if (GetParamIntValue(arg, "timeout=", ref testParams.Timeout)) { } else if (GetParamIntValue(arg, "intf=", ref testParams.Intf)) { } else if (GetParamIntValue(arg, "ep=", ref testParams.Ep)) { testParams.Ep &= 0xf; } else if (GetParamIntValue(arg, "refresh=", ref testParams.Refresh)) { } else if ((value = GetParamStrValue(arg, "mode=")) != null) { if (GetParamStrValue(value, "sync") != null) { testParams.TransferMode = BENCHMARK_TRANSFER_MODE.TRANSFER_MODE_SYNC; } else if (GetParamStrValue(value, "async") != null) { testParams.TransferMode = BENCHMARK_TRANSFER_MODE.TRANSFER_MODE_ASYNC; } else { // Invalid EndpointType argument. CONERR("invalid transfer mode argument! {0}\n", argv[iarg]); return -1; } } else if ((value = GetParamStrValue(arg, "priority=")) != null) { if (GetParamStrValue(value, "lowest") != null) { testParams.Priority = ThreadPriority.Lowest; } else if (GetParamStrValue(value, "belownormal") != null) { testParams.Priority = ThreadPriority.BelowNormal; } else if (GetParamStrValue(value, "normal") != null) { testParams.Priority = ThreadPriority.Normal; } else if (GetParamStrValue(value, "abovenormal") != null) { testParams.Priority = ThreadPriority.AboveNormal; } else if (GetParamStrValue(value, "highest") != null) { testParams.Priority = ThreadPriority.Highest; } else { CONERR("invalid priority argument! {0}\n", argv[iarg]); return -1; } } else if (GetParamIntValue(arg, "packetsize=", ref testParams.IsoPacketSize)) { } else if ((value = GetParamStrValue(arg, "driver=")) != null) { if (GetParamStrValue(value, "winusb") != null) { testParams.Driver = UsbDevice.DriverModeType.WinUsb; } else if (GetParamStrValue(value, "libusb-win32") != null) { testParams.Driver = UsbDevice.DriverModeType.LibUsb; } else if (GetParamStrValue(value, "libusb10") != null) { testParams.Driver = UsbDevice.DriverModeType.MonoLibUsb; } else { CONERR("invalid driver argument! {0}\n", argv[iarg]); return -1; } } else if (GetParamStrValue(arg, "notestselect") != null) { testParams.NoTestSelect = true; } else if (GetParamStrValue(arg, "read") != null) { testParams.TestType = BENCHMARK_DEVICE_TEST_TYPE.TestTypeRead; } else if (GetParamStrValue(arg, "write") != null) { testParams.TestType = BENCHMARK_DEVICE_TEST_TYPE.TestTypeWrite; } else if (GetParamStrValue(arg, "loop") != null) { testParams.TestType = BENCHMARK_DEVICE_TEST_TYPE.TestTypeLoop; } else if (GetParamStrValue(arg, "list") != null) { testParams.UseList = true; } else if (GetParamStrValue(arg, "verifydetails") != null) { testParams.VerifyDetails = true; testParams.Verify = true; } else if (GetParamStrValue(arg, "verify") != null) { testParams.Verify = true; } else { CONERR("invalid argument! {0}\n", argv[iarg]); return -1; } } return ValidateBenchmarkArgs(testParams); }
private static UsbRegDeviceList GetBenchmarkDeviceList(BENCHMARK_TEST_PARAM testParam) { switch (testParam.Driver) { case UsbDevice.DriverModeType.Unknown: UsbDevice.ForceLibUsbWinBack = false; return UsbDevice.AllDevices; case UsbDevice.DriverModeType.LibUsb: UsbDevice.ForceLibUsbWinBack = false; return UsbDevice.AllLibUsbDevices; case UsbDevice.DriverModeType.WinUsb: UsbDevice.ForceLibUsbWinBack = false; return UsbDevice.AllWinUsbDevices; case UsbDevice.DriverModeType.MonoLibUsb: case UsbDevice.DriverModeType.LibUsbWinBack: UsbDevice.ForceLibUsbWinBack=true; return UsbDevice.AllLibUsbDevices; default: throw new ArgumentOutOfRangeException(); } }
private static int GetTestDeviceFromList(BENCHMARK_TEST_PARAM testParam) { UsbRegDeviceList allRegDevices = GetBenchmarkDeviceList(testParam); UsbInterfaceInfo firstInterface; int ret = -1; for (int i = 0; i < allRegDevices.Count; i++) { { UsbRegistry usbRegDevice = allRegDevices[i]; CONMSG("{0}. {1:X4}:{2:X4} {3}\n", i + 1, usbRegDevice.Vid, usbRegDevice.Pid, usbRegDevice.FullName); } } if (allRegDevices.Count == 0) { CONERR0("No devices where found!\n"); ret = -1; goto Done; } CONMSG("\nSelect device (1-{0}) :", allRegDevices.Count); string userInputS = Console.ReadLine(); int userInput; if (int.TryParse(userInputS, out userInput)) ret = 1; else ret = -1; if (ret != 1 || userInput < 1) { CONMSG0("\n"); CONMSG0("Aborting..\n"); ret = -1; goto Done; } CONMSG0("\n"); userInput--; if (userInput >= 0 && userInput < allRegDevices.Count) { testParam.Device = allRegDevices[userInput].Device; if (!ReferenceEquals(testParam.Device, null)) { testParam.Vid = testParam.Device.Info.Descriptor.VendorID; testParam.Pid = testParam.Device.Info.Descriptor.ProductID; if (usb_find_interface(testParam.Device.Configs[0], testParam.Intf, out firstInterface) == null) { // the specified (or default) interface didn't exist, use the first one. if (firstInterface != null) { testParam.Intf = firstInterface.Descriptor.InterfaceID; } else { CONERR("device {0:X4}:{1:X4} does not have any interfaces!\n", testParam.Vid, testParam.Pid); ret = -1; goto Done; } } ret = 0; } } Done: return ret; }
private static int CreateVerifyBuffer(BENCHMARK_TEST_PARAM testParam, ushort endpointMaxPacketSize) { int i; byte indexC = 0; testParam.VerifyBuffer = new byte[endpointMaxPacketSize]; testParam.VerifyBufferSize = endpointMaxPacketSize; for (i = 0; i < endpointMaxPacketSize; i++) { testParam.VerifyBuffer[i] = indexC++; if (indexC == 0) indexC = 1; } return 0; }
private static BENCHMARK_TRANSFER_PARAM CreateTransferParam(BENCHMARK_TEST_PARAM test, int endpointID) { BENCHMARK_TRANSFER_PARAM transferParam; UsbInterfaceInfo testInterface; UsbInterfaceInfo firstInterface; int i; transferParam = new BENCHMARK_TRANSFER_PARAM(); transferParam.Test = test; transferParam.Buffer = new byte[transferParam.Test.BufferCount][]; for (i = 0; i < transferParam.Test.BufferCount; i++) transferParam.Buffer[i] = new byte[transferParam.Test.BufferSize]; if (ReferenceEquals((testInterface = usb_find_interface(test.Device.Configs[0], test.Intf, out firstInterface)), null)) { CONERR("failed locating interface {0:X2}h!\n", test.Intf); FreeTransferParam(ref transferParam); goto Done; } for (i = 0; i < testInterface.EndpointInfoList.Count; i++) { if ((endpointID & 0x80) == 0x80) { // Use first endpoint that matches the direction if ((testInterface.EndpointInfoList[i].Descriptor.EndpointID & 0x80) == 0x80) { transferParam.Ep = test.Device.OpenEndpointReader( (ReadEndpointID) testInterface.EndpointInfoList[i].Descriptor.EndpointID, 0, (EndpointType) (testInterface.EndpointInfoList[i].Descriptor.Attributes & 0x3)); break; } } else { if ((testInterface.EndpointInfoList[i].Descriptor.EndpointID & 0x80) == 0x00) { transferParam.Ep = test.Device.OpenEndpointWriter( (WriteEndpointID) testInterface.EndpointInfoList[i].Descriptor.EndpointID, (EndpointType) (testInterface.EndpointInfoList[i].Descriptor.Attributes & 0x3)); break; } } } if (ReferenceEquals(transferParam.Ep, null)) { CONERR("failed locating EP{0:X2}h!\n", endpointID); FreeTransferParam(ref transferParam); goto Done; } if ((transferParam.Test.BufferSize%transferParam.Ep.EndpointInfo.Descriptor.MaxPacketSize) > 0) { CONERR("buffer size {0} is not an interval of EP{1:X2}h maximum packet size of {2}!\n", transferParam.Test.BufferSize, transferParam.Ep.EndpointInfo.Descriptor.EndpointID, transferParam.Ep.EndpointInfo.Descriptor.MaxPacketSize); FreeTransferParam(ref transferParam); goto Done; } if (test.IsoPacketSize != 0) transferParam.IsoPacketSize = test.IsoPacketSize; else transferParam.IsoPacketSize = transferParam.Ep.EndpointInfo.Descriptor.MaxPacketSize; if (ENDPOINT_TYPE(transferParam) == (byte) EndpointType.Isochronous) transferParam.Test.TransferMode = BENCHMARK_TRANSFER_MODE.TRANSFER_MODE_ASYNC; ResetRunningStatus(transferParam); transferParam.ThreadHandle = new Thread(TransferThreadProc); // If verify mode is on, this is a loop test, and this is a write endpoint, fill // the buffers with the same test data sent by a benchmark device when running // a read only test. if (transferParam.Test.Verify && transferParam.Test.TestType == BENCHMARK_DEVICE_TEST_TYPE.TestTypeLoop && (transferParam.Ep.EndpointInfo.Descriptor.EndpointID & 0x80) == 0) { // Data Format: // [0][KeyByte] 2 3 4 5 ..to.. wMaxPacketSize (if data byte rolls it is incremented to 1) // Increment KeyByte and repeat // byte indexC = 0; int bufferIndex = 0; int transferIndex = 0; UInt16 dataIndex; int packetIndex; int packetCount = ((transferParam.Test.BufferCount*transferParam.Test.BufferSize)/transferParam.Ep.EndpointInfo.Descriptor.MaxPacketSize); for (packetIndex = 0; packetIndex < packetCount; packetIndex++) { indexC = 2; for (dataIndex = 0; dataIndex < transferParam.Ep.EndpointInfo.Descriptor.MaxPacketSize; dataIndex++) { if (dataIndex == 0) // Start transferParam.Buffer[transferIndex][bufferIndex] = 0; else if (dataIndex == 1) // Key transferParam.Buffer[transferIndex][bufferIndex] = (byte) (packetIndex & 0xFF); else // Data transferParam.Buffer[transferIndex][bufferIndex] = indexC++; // if wMaxPacketSize is > 255, indexC resets to 1. if (indexC == 0) indexC = 1; bufferIndex++; if (transferParam.Test.BufferSize == bufferIndex) { bufferIndex = 0; transferIndex++; } } } } Done: if (ReferenceEquals(transferParam, null)) CONERR0("failed creating transfer param!\n"); return transferParam; }
private static UsbDevice Bench_Open(BENCHMARK_TEST_PARAM test) { UsbDevice foundDevice; UsbRegDeviceList usbRegDevices = GetBenchmarkDeviceList(test); foreach (UsbRegistry usbRegDevice in usbRegDevices) { if (usbRegDevice.Vid == test.Vid && usbRegDevice.Pid == test.Pid) { if (usbRegDevice.Open(out foundDevice)) { if (foundDevice.Info.Descriptor.ConfigurationCount > 0) { UsbInterfaceInfo firstInterface; UsbInterfaceInfo foundInterface = usb_find_interface(foundDevice.Configs[0], test.Intf, out firstInterface); if (!ReferenceEquals(foundInterface, null)) { return foundDevice; } } foundDevice.Close(); } } } return null; }
private static int ValidateBenchmarkArgs(BENCHMARK_TEST_PARAM testParam) { if (testParam.BufferCount < 1 || testParam.BufferCount > MAX_OUTSTANDING_TRANSFERS) { CONERR("Invalid BufferCount argument {0}. BufferCount must be greater than 0 and less than or equal to {1}.\n", testParam.BufferCount, MAX_OUTSTANDING_TRANSFERS); return -1; } return 0; }
private static void ShowTestInfo(BENCHMARK_TEST_PARAM testParam) { if (ReferenceEquals(testParam, null)) return; CONMSG("{0} Test Information\n", TestDisplayString[(byte) testParam.TestType & 3]); CONMSG("\tVid / Pid : {0:X4}h / {1:X4}h\n", testParam.Vid, testParam.Pid); CONMSG("\tInterface # : {0:X2}h\n", testParam.Intf); CONMSG("\tPriority : {0}\n", testParam.Priority); CONMSG("\tBuffer Size : {0}\n", testParam.BufferSize); CONMSG("\tBuffer Count : {0}\n", testParam.BufferCount); CONMSG("\tDisplay Refresh : {0} (ms)\n", testParam.Refresh); CONMSG("\tTransfer Timeout: {0} (ms)\n", testParam.Timeout); CONMSG("\tRetry Count : {0}\n", testParam.Retry); CONMSG("\tVerify Data : {0}{1}\n", testParam.Verify ? "On" : "Off", (testParam.Verify && testParam.VerifyDetails) ? " (Detailed)" : ""); CONMSG0("\n"); }