/*Summary * This is a recursive routine for pinning all the buffers used in the transfer in memory. * It will get recursively called QueueSz times. On the QueueSz_th call, it will call * XferData, which will loop, transferring data. */ public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo) { // Allocate one set of buffers for the queue cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN]; xBufs[j] = new byte[BufSz]; oLaps[j] = new byte[20]; //pktsInfo[j] = new ISO_PKT_INFO[PPX]; pktsInfo[j] = new ISO_PKT_INFO[M280DEF.Packet_Xfer]; fixed(byte *tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j]) // Pin the buffers in memory { OVERLAPPED *ovLapStatus = (OVERLAPPED *)tL0; ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0); // Pre-load the queue with a request int len = BufSz; inEndpoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]); j++; if (j < QueueSz) { LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo); // Recursive call to pin next buffers in memory } else { XferData(cBufs, xBufs, oLaps, pktsInfo); // All loaded. Let's go! } } }
public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo) { cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN]; xBufs[j] = new byte[BufSz]; oLaps[j] = new byte[20]; pktsInfo[j] = new ISO_PKT_INFO[M280DEF.Packet_Xfer]; fixed(byte *tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j]) { OVERLAPPED *ovLapStatus = (OVERLAPPED *)tL0; ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0); int len = BufSz; inEndpoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]); j++; if (j < QueueSz) { LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo); } else { XferData(cBufs, xBufs, oLaps, pktsInfo); } } }
private unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo) { CyIsocEndPoint InEndpt = usbdevice.IsocInEndPt; cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN + bulkendpoint.MaxPktSize + ((bulkendpoint.XferMode == XMODE.BUFFERED) ? buffersize : 0)]; xBufs[j] = new byte[buffersize]; oLaps[j] = new byte[20]; pktsInfo[j] = new ISO_PKT_INFO[M280DEF.Packet_Xfer]; fixed(byte *tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j]) { OVERLAPPED *ovLapStatus = (OVERLAPPED *)tL0; ovLapStatus->hEvent = PInvoke.CreateEvent(0, 0, 0, 0); int len = buffersize; bulkendpoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]); j++; if (j < queuesize) { LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo); } else { XferData(cBufs, xBufs, oLaps, pktsInfo); } } }
/*Summary * This is a recursive routine for pinning all the buffers used in the transfer in memory. * It will get recursively called QueueSz times. On the QueueSz_th call, it will call * XferData, which will loop, transferring data, until the stop button is clicked. * Then, the recursion will unwind. */ public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo) { // Allocate one set of buffers for the queue. Buffered IO method require user to allocate a buffer as a part of command buffer, // the BeginDataXfer does not allocated it. BeginDataXfer will copy the data from the main buffer to the allocated while initializing the commands. cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN + IsoPktBlockSize + ((EndPoint.XferMode == XMODE.BUFFERED) ? BufSz : 0)]; xBufs[j] = new byte[BufSz]; oLaps[j] = new byte[20]; pktsInfo[j] = new ISO_PKT_INFO[PPX]; fixed(byte *tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j]) // Pin the buffers in memory { OVERLAPPED *ovLapStatus = (OVERLAPPED *)tL0; ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0); // Pre-load the queue with a request int len = BufSz; EndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]); j++; if (j < QueueSz) { LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo); // Recursive call to pin next buffers in memory } else { XferData(cBufs, xBufs, oLaps, pktsInfo); // All loaded. Let's go! } } }
private void AsysnchonousXferData() { // Setup the queue buffers byte[][] cmdBufs = new byte[QueueSz][]; byte[][] xferBufs = new byte[QueueSz][]; byte[][] ovLaps = new byte[QueueSz][]; ISO_PKT_INFO[][] pktsInfo = new ISO_PKT_INFO[QueueSz][]; }
/*Summary * This is a recursive routine for pinning all the buffers used in the transfer in memory. * It will get recursively called QueueSz times. On the QueueSz_th call, it will call * XferData, which will loop, transferring data, until the stop button is clicked. * Then, the recursion will unwind. */ public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo) { // Allocate one set of buffers for the queue, Buffered IO method require user to allocate a buffer as a part of command buffer, // the BeginDataXfer does not allocated it. BeginDataXfer will copy the data from the main buffer to the allocated while initializing the commands. cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN + IsoPktBlockSize + ((EndPoint.XferMode == XMODE.BUFFERED) ? BufSz : 0)]; xBufs[j] = new byte[BufSz]; //initialize the buffer with initial value 0xA5 for (int iIndex = 0; iIndex < BufSz; iIndex++) { xBufs[j][iIndex] = DefaultBufInitValue; } oLaps[j] = new byte[20]; pktsInfo[j] = new ISO_PKT_INFO[PPX]; fixed(byte *tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j]) // Pin the buffers in memory { OVERLAPPED *ovLapStatus = (OVERLAPPED *)tL0; ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0); // Pre-load the queue with a request int len = BufSz; EndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]); //if (Save == true) //mady //{ // Buffer.BlockCopy(xBufs[j], 0, temp, j * PPX * EndPoint.MaxPktSize, PPX * EndPoint.MaxPktSize); //mady: Take Backup of received data to Temp Buffer //} j++; if (j < QueueSz) { LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo); // Recursive call to pin next buffers in memory } else { XferData(cBufs, xBufs, oLaps, pktsInfo); } } }
public unsafe void XferThread() { byte[][] cmdBufs = new byte[QueueSz][]; byte[][] xferBufs = new byte[QueueSz][]; byte[][] ovLaps = new byte[QueueSz][]; ISO_PKT_INFO[][] pktsInfo = new ISO_PKT_INFO[QueueSz][]; int xStart = 0; try { LockNLoad(ref xStart, cmdBufs, xferBufs, ovLaps, pktsInfo); } catch (NullReferenceException e) { // This exception gets thrown if the device is unplugged // while we're streaming data e.GetBaseException(); //this.Invoke(handleException); } }
private void XferThread() { byte[][] cmdBufs = new byte[queuesize][]; byte[][] xferBufs = new byte[queuesize][]; byte[][] ovLaps = new byte[queuesize][]; ISO_PKT_INFO[][] pktsInfo = new ISO_PKT_INFO[queuesize][]; int xStart = 0; try { LockNLoad(ref xStart, cmdBufs, xferBufs, ovLaps, pktsInfo); } catch (NullReferenceException e) { e.GetBaseException(); dispatcher.Invoke(handleException); } catch (Exception ex) { System.Console.Out.WriteLine(ex.ToString()); } }
private void DataProducer() { // Setup the queue buffers byte[][] cmdBufs = new byte[QueueSz][]; byte[][] xferBufs = new byte[QueueSz][]; byte[][] ovLaps = new byte[QueueSz][]; ISO_PKT_INFO[][] pktsInfo = new ISO_PKT_INFO[QueueSz][]; //int xStart = 0; ////////////////////////////////////////////////////////////////////////////// ///////////////Pin the data buffer memory, so GC won't touch the memory/////// ////////////////////////////////////////////////////////////////////////////// GCHandle cmdBufferHandle = GCHandle.Alloc(cmdBufs[0], GCHandleType.Pinned); GCHandle xFerBufferHandle = GCHandle.Alloc(xferBufs[0], GCHandleType.Pinned); GCHandle overlapDataHandle = GCHandle.Alloc(ovLaps[0], GCHandleType.Pinned); GCHandle pktsInfoHandle = GCHandle.Alloc(pktsInfo[0], GCHandleType.Pinned); try { LockNLoad(cmdBufs, xferBufs, ovLaps, pktsInfo); } catch (NullReferenceException e) { // This exception gets thrown if the device is unplugged // while we're streaming data e.GetBaseException(); //this.Invoke(handleException); } ////////////////////////////////////////////////////////////////////////////// ///////////////Release the pinned memory and make it available to GC.///////// ////////////////////////////////////////////////////////////////////////////// cmdBufferHandle.Free(); xFerBufferHandle.Free(); overlapDataHandle.Free(); pktsInfoHandle.Free(); }
public unsafe void LockNLoad(byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo) { int j = 0; int nLocalCount = j; GCHandle[] bufSingleTransfer = new GCHandle[QueueSz]; GCHandle[] bufDataAllocation = new GCHandle[QueueSz]; GCHandle[] bufPktsInfo = new GCHandle[QueueSz]; GCHandle[] handleOverlap = new GCHandle[QueueSz]; while (j < QueueSz) { // Allocate one set of buffers for the queue, Buffered IO method require user to allocate a buffer as a part of command buffer, // the BeginDataXfer does not allocated it. BeginDataXfer will copy the data from the main buffer to the allocated while initializing the commands. cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN]; xBufs[j] = new byte[BufSz]; //initialize the buffer with initial value 0xA5 for (int iIndex = 0; iIndex < BufSz; iIndex++) { xBufs[j][iIndex] = 0; } int sz = Math.Max(CyConst.OverlapSignalAllocSize, sizeof(OVERLAPPED)); oLaps[j] = new byte[sz]; pktsInfo[j] = new ISO_PKT_INFO[PPX]; /*///////////////////////////////////////////////////////////////////////////// * * fixed keyword is getting thrown own by the compiler because the temporary variables * tL0, tc0 and tb0 aren't used. And for jagged C# array there is no way, we can use this * temporary variable. * * Solution for Variable Pinning: * Its expected that application pin memory before passing the variable address to the * library and subsequently to the windows driver. * * Cypress Windows Driver is using this very same memory location for data reception or * data delivery to the device. * And, hence .Net Garbage collector isn't expected to move the memory location. And, * Pinning the memory location is essential. And, not through FIXED keyword, because of * non-usability of temporary variable. * * /////////////////////////////////////////////////////////////////////////////*/ //fixed (byte* tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j]) // Pin the buffers in memory ////////////////////////////////////////////////////////////////////////////////////////////// bufSingleTransfer[j] = GCHandle.Alloc(cBufs[j], GCHandleType.Pinned); bufDataAllocation[j] = GCHandle.Alloc(xBufs[j], GCHandleType.Pinned); bufPktsInfo[j] = GCHandle.Alloc(pktsInfo[j], GCHandleType.Pinned); handleOverlap[j] = GCHandle.Alloc(oLaps[j], GCHandleType.Pinned); // oLaps "fixed" keyword variable is in use. So, we are good. ///////////////////////////////////////////////////////////////////////////////////////////// unsafe { //fixed (byte* tL0 = oLaps[j]) { CyUSB.OVERLAPPED ovLapStatus = new CyUSB.OVERLAPPED(); ovLapStatus = (CyUSB.OVERLAPPED)Marshal.PtrToStructure(handleOverlap[j].AddrOfPinnedObject(), typeof(CyUSB.OVERLAPPED)); ovLapStatus.hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0); Marshal.StructureToPtr(ovLapStatus, handleOverlap[j].AddrOfPinnedObject(), true); // Pre-load the queue with a request int len = BufSz; if (BulkInEndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]) == false) { Failures++; } } j++; } } XferData(cBufs, xBufs, oLaps, pktsInfo, handleOverlap); // All loaded. Let's go! unsafe { for (nLocalCount = 0; nLocalCount < QueueSz; nLocalCount++) { CyUSB.OVERLAPPED ovLapStatus = new CyUSB.OVERLAPPED(); ovLapStatus = (CyUSB.OVERLAPPED)Marshal.PtrToStructure(handleOverlap[nLocalCount].AddrOfPinnedObject(), typeof(CyUSB.OVERLAPPED)); PInvoke.CloseHandle(ovLapStatus.hEvent); /*//////////////////////////////////////////////////////////////////////////////////////////// * * Release the pinned allocation handles. * * ////////////////////////////////////////////////////////////////////////////////////////////*/ bufSingleTransfer[nLocalCount].Free(); bufDataAllocation[nLocalCount].Free(); bufPktsInfo[nLocalCount].Free(); handleOverlap[nLocalCount].Free(); cBufs[nLocalCount] = null; xBufs[nLocalCount] = null; oLaps[nLocalCount] = null; } } GC.Collect(); }