Exemple #1
0
        // QuickUSB Asynchronous Imaging Example
        void Acquire()
        {
            int k = 0;

            if (!aquiring)
            {
                return;
            }

            // Wait for the transaction to complete (The completion routine will be called)
            do
            {
                qResult = qusb.BulkWait(BulkStream[k], false);
                if (!qResult)
                {
                    qusbError = qusb.LastError();
                    if (qusbError == QuickUsb.Error.Timeout)
                    {
                        // While we wait for this request to complete, we could be performing some
                        // background tasks
                        timer1.Enabled = false;
                        Application.DoEvents();
                        timer1.Enabled = true;
                    }
                }
            } while (!qResult && qusb.LastError() == QuickUsb.Error.Timeout);

            if (!qResult)
            {
                qusbError = qusb.LastError();
                return;
            }
            // Calculate FPS
            QueryPerformanceCounter(out tEnd);
            tElapsed = (double)(tEnd - tStart) / (double)(freq);
            tStart   = tEnd;
            toolStripStatusLabel1.Text = String.Format("FPS: {0:0.0}", 1.0 / tElapsed);

            // Blit data to screen
            BitmapData bData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

            MoveMemory(bData.Scan0, BufferArray[0], FrameByteSize);
            image.UnlockBits(bData);
            pbFrame.Invalidate();

            // Issue a new transaction
            qResult = qusb.ReadBulkDataAsync(
                BufferArray[0],
                FrameByteSize,
                BulkStream[0],
                cbDelegate,
                IntPtr.Zero);

            if (!qResult)
            {
                toolStripStatusLabel1.Text = "Error: Unable to issue data read";
                qusb.Close();
                return;
            }
        }
Exemple #2
0
        private void timer_Tick(object sender, EventArgs e)
        {
            if (numPendingRequests != 0)
            {
                // If we are not multithreading the stream in this example, we must
                // allow time for processing requests.  Processing requests simply
                // means checking if a request has completed, execute its completion
                // routine, and re-issue the requests.  QuickUsb.ProcessStream will
                // return when either any request has completed or the specified time
                // has elapsed.
                if (NumThreads == 0)
                {
                    // Check if the next request has completed
                    bool qResult = qusb.BulkWait(bulkStream[nextRequestToProcess], true); // Don't block
                    if (!qResult)
                    {
                        qusbError = qusb.LastError();
                        if (qusbError != QuickUsb.Error.NotCompleted)
                        {
                            Console.WriteLine("ProcessStream failed with error {0}", qusbError);
                        }
                    }
                }
            }
            else
            {
                // All the requests have completed
                bIssueRead.Enabled  = true;
                bIssueWrite.Enabled = true;
                timer.Stop();

                // Close the module now that we're done with it
                qusb.Close();
            }

            // Report our data throughput
            dataRate.Text = String.Format("Data Rate: {0:0.0} MB/s Overall, {1:0.0} MB/s Instantaneously", overallRate, instRate);

            // Dump data to log
            lock (log)
            {
                tbLog.AppendText(log.ToString());
                log = new StringBuilder();
            }
        }
Exemple #3
0
        private void performTest()
        {
            // Open the module
            string[] modules = QuickUsb.FindModules();
            if (modules.Length == 0)
            {
                return;
            }
            qusb = new QuickUsb(modules[0]);
            qusb.Open(modules[0]);

            int  k, transBytes = 0;
            bool transOk;

            // Async Variables
            QuickUsb.BulkStream[] pBulkStream = null;
            ushort[][]            pDataBuffer = null;
            AsyncBulkStreamTag[]  asyncTag    = null;
            GCHandle[]            hAsyncTag   = null;

            // Legacy Async Variables
            int issuedTrans = 0, nextToComplete = 0;

            IntPtr[] bufferArray = null;
            byte[]   transId     = null;

            // Streaming Variables
            bool streaming = false;

            int dataSize   = 0;
            int numBuffers = 0;

            byte[] data = null;
            uint   size, bytesTransferred;

            QuickUsb.Error qusbError;

            // Start timing
            QueryPerformanceCounter(out startTime);

            // Perform the test
            do
            {
                // Check for modification to configuration parameters
                if (dataSize != testPackSize || numBuffers != (int)nNumBuffers.Value)
                {
                    dataSize   = testPackSize;
                    numBuffers = (int)nNumBuffers.Value;

                    if (rbSync.Checked)
                    {
                        data = new byte[dataSize];
                    }

                    if (rbAsync.Checked)
                    {
                        // Wait for all issued transactions to complete
                        while (issuedTrans > 0)
                        {
                            if (!qusb.BulkWait(pBulkStream[nextToComplete], false))
                            {
                            }
                            else
                            {
                                transOk = true;
                                --issuedTrans;
                                if (++nextToComplete == pBulkStream.Length)
                                {
                                    nextToComplete = 0;
                                }
                            }
                        }

                        // Free memories
                        if (hAsyncTag != null)
                        {
                            for (k = 0; k < hAsyncTag.Length; ++k)
                            {
                                hAsyncTag[k].Free();
                            }
                        }

                        // Allocate memories
                        pDataBuffer = new ushort[numBuffers][];
                        pBulkStream = new QuickUsb.BulkStream[numBuffers];
                        asyncTag    = new AsyncBulkStreamTag[numBuffers];
                        hAsyncTag   = new GCHandle[numBuffers];
                        for (k = 0; k < numBuffers; ++k)
                        {
                            pBulkStream[k]       = new QuickUsb.BulkStream();
                            pDataBuffer[k]       = new ushort[dataSize / 2];
                            asyncTag[k]          = new AsyncBulkStreamTag();
                            hAsyncTag[k]         = GCHandle.Alloc(asyncTag[k], GCHandleType.Pinned);
                            asyncTag[k].shutdown = 0;
                        }

                        // Reset varaibles
                        issuedTrans    = 0;
                        nextToComplete = 0;

                        // Issue new transactions
                        while (issuedTrans != numBuffers)
                        {
                            if (!qusb.ReadBulkDataAsync(pDataBuffer[nextToComplete], (uint)dataSize, pBulkStream[nextToComplete], AsyncCompletionRoutineDelegate, GCHandle.ToIntPtr(hAsyncTag[nextToComplete])))
                            {
                            }
                            else
                            {
                                ++issuedTrans;
                                if (++nextToComplete == numBuffers)
                                {
                                    nextToComplete = 0;
                                }
                            }
                        }
                    }

                    if (rbAsyncLegacy.Checked)
                    {
                        // Wait for all issued transactions to complete
                        while (issuedTrans > 0)
                        {
                            if (!qusb.AsyncWait(out bytesTransferred, transId[nextToComplete], false))
                            {
                            }
                            else
                            {
                                transOk = true;
                                --issuedTrans;
                                if (++nextToComplete == transId.Length)
                                {
                                    nextToComplete = 0;
                                }
                            }
                        }

                        // Free old memories
                        if (bufferArray != null)
                        {
                            for (k = 0; k < bufferArray.Length; ++k)
                            {
                                Marshal.FreeHGlobal(bufferArray[k]);
                            }
                        }

                        // Allocate memories
                        transId     = new byte[numBuffers];
                        bufferArray = new IntPtr[numBuffers];
                        for (k = 0; k < bufferArray.Length; ++k)
                        {
                            bufferArray[k] = Marshal.AllocHGlobal(dataSize);
                        }

                        // Reset varaibles
                        issuedTrans    = 0;
                        nextToComplete = 0;
                    }

                    if (rbStreaming.Checked)
                    {
                        // Stop the stream if one is running
                        if (streaming)
                        {
                            if (!qusb.StopStream(streamID, false))
                            {
                            }
                        }

                        // Restart the stream with new parameters
                        if (!qusb.ReadBulkDataStartStream(IntPtr.Zero, (uint)numBuffers, (uint)dataSize, StreamCompletionRoutineDelegate, IntPtr.Zero, out streamID, 4, 2))
                        {
                        }
                    }
                }

                // Perform the data R/W
                size    = (uint)dataSize;
                transOk = false;
                if (testRead)
                {
                    // Synchronous data read
                    if (rbSync.Checked)
                    {
                        if (!qusb.ReadData(data, ref size))
                        {
                            qusbError = qusb.LastError();
                            // Error
                            MessageBox.Show(String.Format("QuickUsbReadData() failed! - {0}", qusbError.ToString()), "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            quit       = true;
                            transBytes = 0;
                            size       = 0;
                        }
                        else if ((int)size != dataSize)
                        {
                            // Error
                            MessageBox.Show(String.Format("QuickUsbReadData() did not read correct amount of data ({0} of {1} bytes)!", size, dataSize), "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            quit       = true;
                            transBytes = 0;
                            size       = 0;
                        }
                        else
                        {
                            transOk     = true;
                            totalBytes += size;
                        }
                    }

                    // Asynchronous data read
                    else if (rbAsync.Checked)
                    {
                        transOk = true;
                        lock (testThread)
                        {
                            size        = (uint)streamBytes;
                            streamBytes = 0;
                        }
                    }

                    // Legacy asynchronous data read
                    else if (rbAsyncLegacy.Checked)
                    {
                        // First wait on the next transaction to complete
                        bytesTransferred = 0;
                        if (issuedTrans > 0)
                        {
                            if (!qusb.AsyncWait(out bytesTransferred, transId[nextToComplete], false))
                            {
                                qusbError = qusb.LastError();
                                // Error
                                MessageBox.Show("Error", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                quit       = true;
                                transBytes = 0;
                                size       = 0;
                            }
                            else
                            {
                                transOk = true;
                                --issuedTrans;
                            }
                        }

                        // Issue new transactions
                        while (issuedTrans != numBuffers && !quit)
                        {
                            if (!qusb.ReadDataAsync(bufferArray[nextToComplete], ref size, out transId[nextToComplete]))
                            {
                                qusbError = qusb.LastError();
                                // Error
                                MessageBox.Show("Error", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                quit       = true;
                                transBytes = 0;
                                size       = 0;
                            }
                            else
                            {
                                ++issuedTrans;
                                if (++nextToComplete == numBuffers)
                                {
                                    nextToComplete = 0;
                                }
                            }
                        }

                        if (transOk)
                        {
                            size = bytesTransferred;
                        }
                    }

                    // Streaming data read
                    else if (rbStreaming.Checked)
                    {
                        transOk = true;
                        lock (testThread)
                        {
                            size        = (uint)streamBytes;
                            streamBytes = 0;
                        }

                        // Nothing to do here
                        Thread.Sleep(250);
                    }
                }
                else if (rbSync.Checked)
                {
                    // Sychronous data write
                    if (!qusb.WriteData(data, size))
                    {
                        qusbError = qusb.LastError();
                        // Error
                        MessageBox.Show("QuickUsbWriteData() failed!", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        quit       = true;
                        transBytes = 0;
                        size       = 0;
                    }
                    else
                    {
                        transOk     = true;
                        totalBytes += size;
                    }
                }

                if (transOk)
                {
                    transBytes += (int)size;
                }
            } while (!quit);

            if (rbAsync.Checked)
            {
                // Wait for all issued transactions to complete
                for (k = 0; k < pBulkStream.Length; ++k)
                {
                    asyncTag[k].shutdown = 1;
                }

                // Wait for pending transactions to complete
                qusb.BulkWait(null, false);

                /*while (issuedTrans > 0)
                 * {
                 *  if (!qusb.BulkWait(pBulkStream[nextToComplete], false))
                 *  {
                 *  }
                 *  else
                 *  {
                 *      transOk = true;
                 *      --issuedTrans;
                 *      if (++nextToComplete == numBuffers)
                 *      {
                 *          nextToComplete = 0;
                 *      }
                 *  }
                 * }*/

                // Free memory
                for (k = 0; k < pBulkStream.Length; ++k)
                {
                    hAsyncTag[k].Free();
                }
            }

            if (rbAsyncLegacy.Checked)
            {
                // Wait for all issued transactions to complete

                /*while (issuedTrans > 0)
                 * {
                 *  qusb.AsyncWait(out size, transId[nextToComplete], false);
                 *
                 *  --issuedTrans;
                 *  if (++nextToComplete == numBuffers)
                 *  {
                 *      nextToComplete = 0;
                 *  }
                 * }*/
            }

            if (rbStreaming.Checked)
            {
                // Stop the stream if one is running
                if (streaming)
                {
                    if (!qusb.StopStream(streamID, false))
                    {
                        qusbError = qusb.LastError();
                        // Error
                        MessageBox.Show("Error", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }

            qusb.Close();

            if (rbAsyncLegacy.Checked)
            {
                // Free memory
                for (k = 0; k < bufferArray.Length; ++k)
                {
                    Marshal.FreeHGlobal(bufferArray[k]);
                }
            }
        }
Exemple #4
0
        ///////////////////////////////////
        // QuickUSB Asynchronous Example //
        ///////////////////////////////////
        static void Main(string[] args)
        {
            // The number of data buffers to use.  An asynchronous data request is issued
            // for each data buffer, then the main thread waits for each request to complete
            // then issues a new asynchrnonous request using the same data buffer as the
            // completed request.  To maximize throughout, the number of buffers should be
            // at least equal to the number of threads (see the SETTING_THREADS setting).
            const int NumBuffers = 8;

            // The byte size of the buffers.  To maximize performance the buffer size should
            // be as large as possible and a power of 2.
            const int BufferByteSize = 512 * 1024; // 512 KB

            // The number of times to issue a request for each buffer.
            const int LOOPS = 50;

            // Variables
            int k, j, Id = 0;

            string[] nameList;
            bool     qResult;

            QuickUsb.Error qusbError;

            // Variables to track time and performace
            long   tStart, tEnd, freq;
            double tElapsed;

            // The data buffers, BulkStream objects, and tag objects.  Because these objects
            // are passed to and used by unmanaged code in QuickUSB land, they must be handled
            // with care.  They cannot be relocated by the garbage collector and must either
            // be pinned or allocated in unmanaged memory.
            ushort[][]            BufferArray = new ushort[NumBuffers][];
            QuickUsb.BulkStream[] BulkStream  = new QuickUsb.BulkStream[NumBuffers];
            BulkStreamTag[]       tag         = new BulkStreamTag[NumBuffers];

            // We must keep an active reference to the delegate so it is not garbage collected.
            // This reference must minimally stay alive until all pending asynchronous requests
            // have completed.
            QuickUsb.BulkStreamCompletionRoutine cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine);

            // Query connected modules
            nameList = QuickUsb.FindModules();
            if (nameList.Length == 0)
            {
                Console.WriteLine("No modules found.");
                return;
            }

            // Open the first module
            qusb = new QuickUsb(nameList[0]);
            qusb.Open(nameList[0]);

            // Allocate buffers
            for (k = 0; k < NumBuffers; ++k)
            {
                // Allocate the data buffers in unmanaged memory
                BufferArray[k] = new ushort[BufferByteSize / 2];

                // Allocate the BulkStream objects
                BulkStream[k] = new QuickUsb.BulkStream();

                // Create the tag object as normal.  We will later get a pinned reference to this
                // object to use in issuing the request, that we will later be able to use to
                // reconstruct a reference to the managed tag object in the completion routine.
                // We can do this because the tag data is never accessed or modified in unmanaged
                // land and only ever used in managed land.
                tag[k] = new BulkStreamTag();
            }

            // Start throughput timer
            QueryPerformanceFrequency(out freq);
            QueryPerformanceCounter(out tStart);

            Console.WriteLine("Acquiring data...please wait");

            // Aquire
            for (j = 0; j < (LOOPS + 1); ++j)
            {
                for (k = 0; k < NumBuffers; ++k)
                {
                    // If this is not the first loop, wait for the last transaction to complete
                    if (j != 0)
                    {
                        // Wait for the transaction to complete.  Once this function returns successfully
                        // the completion routine has already been executed and the transaction is
                        // entirely complete.
                        qResult = qusb.BulkWait(BulkStream[k], false);
                        if (!qResult)
                        {
                            qusbError = qusb.LastError();
                            Console.WriteLine("Request failed (QuickUSB Error: {0})", qusb.LastError());
                        }
                        else
                        {
                            // Now that this request has completed we may process the data here or in the
                            // completion routine, though it is better to perform all processing in the
                            // completion routine as they can be multi-threaded, allowing the main thread
                            // to simply issue and re-issue data requests.
                        }
                    }

                    // If this is not the last loop, issue a new transaction
                    if (j != LOOPS)
                    {
                        //Console.WriteLine("Issuing Request #{0}", (Id + 1));

                        // Issue a new transaction
                        tag[k].Id = ++Id;
                        qResult   = qusb.ReadBulkDataAsync(
                            BufferArray[k],
                            BufferByteSize,
                            BulkStream[k],
                            cbDelegate,
                            GCHandle.ToIntPtr(GCHandle.Alloc(tag[k])));

                        if (!qResult)
                        {
                            Console.WriteLine(String.Format("QuickUSB Error: {0}", qusb.LastError()));
                            qusb.Close();
                            return;
                        }
                        else
                        {
                            ++RefCount;
                            ++TransCount;
                        }
                    }
                }
            }

            // Stop the throughput timer
            QueryPerformanceCounter(out tEnd);
            tElapsed = (double)(tEnd - tStart) / (double)(freq);
            Console.WriteLine();

            Console.WriteLine("Time elapsed: {0:0.000} s", tElapsed);
            Console.WriteLine("Total bytes transferred: {0:0.000} MB", ((float)TotalBytes / (1024.0 * 1024.0)));
            Console.WriteLine("Data rate: {0:0.000} MS/s", ((TotalBytes / (1024.0 * 1024.0)) / tElapsed));
            Console.WriteLine();

            // Close the module
            qResult = qusb.Close();
            if (!qResult)
            {
                Console.WriteLine("QuickUSB Error: {0}", qusb.LastError());
                return;
            }

            // Report any leaks or errors
            Console.WriteLine("{0} transaction(s) issued in total", TransCount);
            Console.WriteLine("{0} transaction(s) failed", ErrorCount);
            Console.WriteLine("{0} transaction(s) are still outstanding", RefCount);

            return;
        }