阅读:6503回复:15
求助:CyUSB,如何实现ISO传输的数据是连续的?(急!!!)
现在在用CyUSB.sys写数据采集系统,调用CCyIsocEndPoint的BeginDataXfer\WaitForXfer\FinishDataXfer完成一次ISO传输,然而每两次ISO传输间的数据丢了?这是怎么回事呢?
XDJM们,有没有用过CyUSB.sys的,怎么进行连续的ISO传输呢? 项目急,小妹感激不尽啊!!! |
|
沙发#
发布于:2007-03-23 11:48
我遇到的情况与你类似,
请问你用fx2吗?另外你的设计思路能不能讨论一下: qq:22952089 |
|
|
板凳#
发布于:2007-03-23 11:49
CyUSB.sys是那个型号对应的驱动?与 ezusb.sys有何区别? 有源代码吗?
|
|
|
地板#
发布于:2007-03-25 19:55
好像是cypress最新的驱动,可能是ezusb.sys的升级版
引用第2楼wjt810907于2007-03-23 11:49发表的“”: |
|
地下室#
发布于:2007-03-26 09:34
谢谢楼上,我去cpress官方网站看看
|
|
|
5楼#
发布于:2007-03-26 18:55
哈!
问题解决了,不丢数据了,狂喜。。。 QQ:19549106 |
|
6楼#
发布于:2007-03-26 19:01
请问你是怎么做到不丢数据的?
能介绍一下经验吗? |
|
|
7楼#
发布于:2007-04-06 19:52
有问题来求救,解决了就溜号!
不厚道啊. |
|
8楼#
发布于:2007-04-06 20:44
一般是用ping pang方式吧。就是开始时下同时两个urb抓数据,这样一个完成时,另一个自动被执行,当前完成的处理完毕再下urb,这样交替执行。
|
|
9楼#
发布于:2007-04-09 08:51
引用第5楼apple343于2007-03-26 18:55发表的“”: 能介绍一下经验吗?我也被这个问题困扰 |
|
|
10楼#
发布于:2007-04-09 09:27
引用第8楼Delphips于2007-04-06 20:44发表的“”: 请问上述方法要如何实现? |
|
11楼#
发布于:2007-04-10 12:34
哈!看来和我遇到同样问题的人还挺多的,最近挺忙的,没顾得上贴出解答,见谅噢!
依我的理解,我很同意?楼的观点,是用ping pong buffer保持ISO stream,也就是ISO_TRANSFER_CONTROL(见ezusb.sys源代码)这个结构,它会帮你缓存采到的数据。采集开始之前先要设置好ISO_TRANSFER_CONTROL数据结构的最重要两个参数,FramesPerBuffer和BufferCount,推荐设置FramesPerBuffer=10,BufferCount=2。然后每次读取数据调用DeviceIoControl(m_hDeviceHandle, IOCTL_EZUSB_READ_ISO_BUFFER, &m_IsoADControl,//关键部分,就是之前设置的ISO_TRANSFER_CONTROL sizeof(ISO_TRANSFER_CONTROL), m_data,//此次传输获取的数据 bytesToRead, &nBytes, NULL); 但这是对Cpress公司以前提供的Ezusb.sys来说的保持ISO stream的解决方法,只需要设置好FramesPerBuffer和BufferCount(至少为2),然后DeviceIoControl获取数据就OK了。至于底层如何ping pong这BufferCount个buffer,就没有必要详细了解了:) 以上都是针对Ezusb.sys的处理方法,那换作CyUSB.sys呢?还有ISO_TRANSFER_CONTROL帮忙ping pong吗?我找了半天也没找到:( 看来要用CYAPI里的函数,就得自己控制ISO stream。 我用一个线程专门负责采数据,以下是核心代码: int i = 0; PUCHAR *buffers = new PUCHAR[QueueSize];//此处QueueSize相当于上面提到的BufferCount,推荐设置4 CCyIsoPktInfo **isoPktInfos = new CCyIsoPktInfo*[QueueSize]; PUCHAR *contexts = new PUCHAR[QueueSize]; OVERLAPPED inOvLap[MAX_QUEUE_SZ]; long len = EndPt->MaxPktSize * PPX; // Packets per Xfer,每次Xfer传输的包数,推荐设置64(8的整数倍) EndPt->SetXferSize(len); for (i=0; i< QueueSize; i++) { buffers = new UCHAR[len]; isoPktInfos = new CCyIsoPktInfo[PPX]; inOvLap.hEvent = CreateEvent(NULL, false, false, NULL); memset(buffers,0,len); contexts = EndPt->BeginDataXfer(buffers, len, &inOvLap); if (EndPt->NtStatus || EndPt->UsbdStatus) // BeginDataXfer failed { AbortXferLoop(i+1, buffers,isoPktInfos,contexts,inOvLap); return; } } i=0; for (;bStreaming;) { long rLen = len; if (!EndPt->WaitForXfer(&inOvLap, TimeOut)) { EndPt->Abort(); if (EndPt->LastError == ERROR_IO_PENDING) WaitForSingleObject(inOvLap.hEvent,2000); } if (EndPt->Attributes == 1) // ISOC Endpoint { if (EndPt->FinishDataXfer(buffers, rLen, &inOvLap, contexts, isoPktInfos)) { CCyIsoPktInfo *pkts = isoPktInfos; for (int j=0; j< PPX; j++) { if (pkts[j].Status == 0) { BytesXferred += pkts[j].Length; Successes++; } else Failures++; pkts[j].Length = 0; } } else Failures++; } contexts = EndPt->BeginDataXfer(buffers, len, &inOvLap);//重新提交,保持ISO Stream if (EndPt->NtStatus || EndPt->UsbdStatus) // BeginDataXfer failed { AbortXferLoop(QueueSize,buffers,isoPktInfos,contexts,inOvLap); return; } i++; if (i == QueueSize) { i=0; } } 上述代码只用稍作改动,就应该可以实现在CyUSB.sys上的ISO连续传输,Bulk类似:),注意中止线程时别忘了释放分配的内存. 有什么理解不对的地方,也请大家指正噢! |
|
12楼#
发布于:2007-04-10 12:45
请问你怎么知道数据正确呢?我也好是这样做的,但是包的大小对了又不能保证里面的数据都正确?
|
|
|
13楼#
发布于:2007-04-10 12:48
事实证明我的iso传输有1/1500~1/2000的错误率
我将数据用线程写到文件中,然后用matlab进行分析 数据用fpga进行了编号 按理说我实现了你的这一步,现在我怀疑是不是fpga与fx2通讯的问题,因为问题不一定是驱动的问题 |
|
|
14楼#
发布于:2009-11-03 14:50
不知道楼上的和楼主的数据传输能达到多少速度
|
|
15楼#
发布于:2009-11-13 19:37
又是不了了之的
|
|