- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Myself and another poster here, andy, both experienced this problem and found solutions. Andy tried to contact Cypress and tell them about it, but he says they just ignored him. I posted here so that anyone else who runs into the problem might find a solution. We had a nice thread going three weeks ago, but it's not here anymore. I assume Cypress removed it, so I won't be surprised if this gets removed, too.
At least the C++ library and driver work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
what was the reason of removing it?
I added that thread to my bookmarks and now wonder why it is unreachable...
I agree with you, there is a bug - when you not pin the byte buffers before pass them to the xfer functions of the lib, the application can freeze or end in mysterious exceptions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would like to assure you that we did not remove the thread in question from the forum. In the past, I have faced a similar issue with a post in psoc forums, which was then restored by our web team.
peretus4,
Can you provide me with the link to the thread (from your bookmark) that disappeared so that I can try to locate it?
I would also like to assure you that I will bring up this issue with the concerned team and initiate corrective actions to fix any bug int he C#.NET library.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have an old response notification email. The URL was
http://www.cypress.com/forums/...readid=8246&forumid=1
There was more to it than "need to pin buffers". There was an overlapped size allocation issue and an unnecessary ref issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Basically, the Overlapped structure (wraps the buffers and commands to pass over the fence to unmanaged) gets moved or cleaned by the GC. It seems fairly rare but if you are pushing a lot of data through multiple endpoints, you WILL experience an ExecutionEngineException or NullReferenceException in Mscorlib.dll often enough to render your code "un-depoyable".
My solution: Only use the Cyusb.dll to for initialization and housekeeping. Since I am almost saturating the bandwidth and doing a lot of SW processing, I chose a very asynchronous approach. Here is a VERY terse description (check out the "concurrent affairs" series of articles published in MSDN magazine by Jeffery Richter for details...I based my approach off of his model)
Once you have an OS handle you can use Threadpool.bindhandle()
-this causes the threadpool to process the callbacks for overlappedIO operations
Implement IAsyncResult to handle the Packing and unPacking of the NativeOverlapped structure and the basic async pattern
Call DeviceIO Control with a callback function. I allocate a byte[] buffer inside my ReadData method and create a callback (using a lambda expression) that uses this same byte buffer to pass along to my DeviceIoControl method. The buffers get pinned using GCHandle.Alloc & get "Pack()"ed along with the commands and callback into the NativeOverlapped structure. All of these are passed into DeviceIoControl.
This allows you to queue up multiple commands to the endpoints with pre-allocated buffers that are automatically called one-at-a-time by the OS and processed (by the callback) by the threadpool as it's scheduled. "Set it and forget it!" as Ron Popeil would say...
Anyway, the gist is: Even the blocking "non asynchronous" XferData functions provided in the API are just blocking wrappers around the asynchronous calls. However, they are not implemented correctly and leave the door wide open for the GC to corrupt the heap.
PM or e-mail me if you would like more info and I'll try to help as best I can.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You don't need to write unmanaged code to solve the problem. Just use the GCHandle class to pin all three byte[] buffers before passing them to any of the CyAPI Xfer functions. Cypress could easily pin the three buffers inside XferData before sending them to the driver, and un-pin before returning from XferData. Six lines of code and XferData would no longer cause crashes.
GCHandle bufHandle1 = GCHandle.Alloc(data, GCHandleType.Pinned);
GCHandle bufHandle2 = GCHandle.Alloc(singleXfer, GCHandleType.Pinned);
GCHandle bufHandle3 = GCHandle.Alloc(overlap, GCHandleType.Pinned);
// send buffers to driver
// wait for driver to finish using the buffers
// get the results of the transfer
bufHandle1.Free();
bufHandle2.Free();
bufHandle3.Free();
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That thread had disappeared due to a bug. It has been restored. I have also written to the concerned team to have a look at this issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you could, pass these on too.
1) OverlapSignalAllocSize should be a static member of CyConst, but instead it's a non-static member of CyUSBEndPoint. This is contrary to the documentation.
2) byte[] does not need to be passed as a ref parameter. Only value-types need to be passed as a ref parameter. When an array, or any other reference type, is passed as a non-ref parameter, the reference (NOT the array!) is passed by value (i.e. a pointer is copied).
This is very different from C++, where an array must be passed by reference using & or the copy constructor would make a copy of the whole array. Using a ref parameter for byte[] is like passing a pointer by reference in C++, like say
C#
bool XferData(ref byte[] buf, ref int len);
is like
C++
bool XferData(PCHAR &data, LONG &len);
i.e. passing a pointer by reference.
---
This does not match the actual C++ library,
bool XferData(PCHAR data, LONG &len);
Which looks like this in C#
bool XferData(byte[] buf, ref int len);
i.e. passing a pointer by value
Passing byte[] as a ref parameter adds unnecessary complexity to your customer's code by adding serious and unnecessary restrictions on what may be used as an argument.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The software guys went through the XferData API implementation and did not find any loop hole in it. It does pining of all allocation properly.
- XferData API is being used by all C# application(Bulk Loopback / Control Center / Screamer), which passed through the stress testing and did not find such issue.
Find the source code for the XferData API below.
public unsafe virtual bool XferData(ref byte[] buf, ref int len)
{
byte[] ovLap = new byte[OverlapSignalAllocSize];
fixed( byte *fixedOvLap = ovLap)
{
OVERLAPPED *ovLapStatus = (OVERLAPPED*) fixedOvLap;
ovLapStatus->hEvent = PInvoke.CreateEvent(0, 0, 0, 0);
// This SINGLE_TRANSFER buffer must be allocated at this level.
int bufSz = CyConst.SINGLE_XFER_LEN + ((XferMode == XMODE.DIRECT) ? 0 : len);
byte[] cmdBuf = new byte[bufSz];
// These nested fixed blocks ensure that the buffers don't move in memory
// While we're doing the asynchronous IO - Begin/Wait/Finish
fixed (byte* tmp1 = cmdBuf, tmp2 = buf)
{
bool bResult = BeginDataXfer(ref cmdBuf, ref buf, ref len, ref ovLap);
//
// This waits for driver to call IoRequestComplete on the IRP
// we just sent.
//
bool wResult = WaitForIO(ovLapStatus->hEvent);
bool fResult = FinishDataXfer(ref cmdBuf, ref buf, ref len, ref ovLap);
PInvoke.CloseHandle(ovLapStatus->hEvent);
return wResult && fResult;
}
}
}
Adding this API instead of callling CyUSB.dll XferData API will probably help.
Thanks
VIVK
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the reply. I really appreciate the support that you are providing.
The fixed pointers tmp1 and tmp2 are not referenced in the fixed block. The compiler will warn you about this and potentially optimize the fixed block out. To make things more complicated, this optimization will only happen with Release build, so if your developers were testing a Debug build, you would not encounter this error.
To verify, I suggest using Reflector on the Release mode assembly and looking at XferData to see if the fixed block survived optimization.
Cheers,
Andrew Sobotka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I created a technical support case with you as a contact and routed it to the concerned engineer. Let me know if you are able to view the case.
Once the issue is resolved, I will post the same in the forum for the benefit of the others.
Cheers
VIVK
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have looked in the list of support cases which I have previously had open, and all of the cases are closed. There are no new ones.
By the way, I took the time to do a test on the XferData example you provided above. Using Reflector, I was able to verify that the problem only occurs for Release builds.
Specifically, when the "Optomize Code" checkbox in the Project Properties' Build box is checked, like for Release builds, the compiler will optimize the fixed block away because the fixed pointers are unreferenced. If Optimize Code is not checked, like for Debug builds, the fixed block survives.
I have a copy of the Reflector output to share with the engineer when I gain access to the technical support case.
Cheers,
Andrew
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't mind helping. But, I'm probably gonna be too busy to contribute much over the next few months.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you please provide the case number of any of your closed cases? That will help us to locate your account and reassign this new case to your account so that you can view it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi all,
i meet this issue. Did this issus is fixed by cypress?
Or we just only use the solution by andrew provided
==========================================================================
GCHandle bufHandle1 = GCHandle.Alloc(data, GCHandleType.Pinned);
GCHandle bufHandle2 = GCHandle.Alloc(singleXfer, GCHandleType.Pinned);
GCHandle bufHandle3 = GCHandle.Alloc(overlap, GCHandleType.Pinned);
// send buffers to driver
// wait for driver to finish using the buffers
// get the results of the transfer
bufHandle1.Free();
bufHandle2.Free();
bufHandle3.Free();
==========================================================================
any help is appreciate!
regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It was fixed long back. Are you seeing the exact same error behavior?
Regards,
Anand
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am having a similar problem using the cy8c24894 as a low speed USB control interface (and some other functions) to an FPGA. I keep having issues using xfrdata. I did a one-button test app in C# (VS10) that sends a string to the PSoC, which then echos it back. When I click a button the main thread sends a string. A separate timer thread checks periodically for the echo and puts the echo on the test app GUI. It works for a time, but fails with memory issues. It sometimes won't terminate until I unplug the PSoC, then it terminates immediately. When it terminates on its own, I can re-run the app without resetting the PSoC and it works for a while before it fails again. The one-button test app is copied from the template in the CyUSB.net suite with a timer added. The error I get most often is:
The program '[1896] Template.vshost.exe: Managed (v2.0.50727)' has exited with code -1073740940 (0xc0000374).
Any help would be appreciated; I am trying to bring up the first of two boards which will use this basic architecture.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Update: I got rid of the separate timer thread and just put in a loop that sends a 4 byte buffer string and then waits for a response (the echo) on each iteration of the loop. It almost always hangs on the receive of the 32nd packet.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I concur there is a bug. I made my own xferdata function using the code posted on 3/10 and replacing the fixed directives with Andrew's GCHandle.Alloc suggestions. At this point I can make the problem come and go by changing the name of the called function from the re-written xferdata function to the library function without changing anything else. Proof positive for me, but I don't understand why it works. The fixed directives should do exactly the thing (ie. prevent the garbage collector from prematurely reclaiming transfer buffers), but one works and one doesn't.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For what it's worth:
I've also ran into this issue, and Andrew's solution solved it for me.
I'm using a queue, so after creating each buffer for that queue, I pinned them. At the very end of program operation, I Abort() my enpoint once for each queued call, and then Free() the handle. This way, we're reaching 19MB/s in a stable way (possibly more, but we're targeting 19MB/s).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for sharing this details here.
-PRJI