阅读:2585回复:14
【分享】USB通信,PC端通信编程及常见问题解决方法请教:68013USB通信,PC端读取数据时程序反应慢的解决方法 上文为我昨天发的帖子,多谢zhoujiamurong和summerfruit朋友的热心帮助。现问题已经解决,如前承诺,将经验和大家分享,希望我走过的弯路,大家不要再走了。 USB入手真是不太容易,光USB协议都那么多,每一款都又有好几百页的芯片手册,涉及到的东西包括固件、驱动和通信,做起来真的不容易。一个地方没有看到,可能就在那停滞不前了。 我用的是Cy7c68013芯片,用于DSP与上位机传输大量数据(目前传输速度最快测试可以达到20M Byte/s)。 有时间我会将开发过程中的经验与大家分享下 |
|
沙发#
发布于:2008-07-22 13:36
为什么程序反应慢,我想应该是有个函数在一直检测,直到有数据或设备断开时才返回。研究了下驱动,没找到原因。如果能改成没有数据就返回0就不至于这么慢了。
驱动没有做过,还请各位指点。 我现在是用Delphi调用C写的动态链接库通信,如果哪位朋友需要参考,我可以提供一些方法。 |
|
驱动小牛
|
板凳#
发布于:2008-07-22 14:22
程序就等待读取完成,程序假死,造成程序响应比较慢
============ 这个使用线程是否是后台的工作线程,还是直接用的死循环在用户线程中跑的? 如果是后台线程还是假死,看读取的时候是否是停滞在ReadFile等待返回? 如果是寻找是否有异步读取的方法?一般驱动里面都是异步的,改应该改在应用层。 |
地板#
发布于:2008-07-22 14:38
你可以在驱动中自建一个thread,在这个thread中发送读URB,然后等待返回,读到数据放入buffer里面,读不到这个包含URB的IRP会pending的。主程序继续运行。
|
|
地下室#
发布于:2008-07-22 14:41
如果不想自建thread,可以调用系统线程,使用work item。
|
|
5楼#
发布于:2008-07-22 14:54
引用第2楼zhoujiamurong于2008-07-22 14:22发表的 : 多谢楼上两位指点!我使用的是如下过程读取USB数据。创建一个线程,死循环读数据放到Buffer中,主循环中处理这些数据。读的时候,如果我的MCU不发数据的话,就等待读取Pending。 正像你说的,停滞在ReadFile等待返回。 int _stdcall ReadData(char *pbuf) { DWORD nBytes; BOOL bResult; if(hDevice!=INVALID_HANDLE_VALUE) { bulkControl.pipeNum = 1; // Pipe 1 (EP 6) bResult = DeviceIoControl(hDevice, // 设备句柄 IOCTL_EZUSB_BULK_READ, // 控制码 &bulkControl, // 输入数据缓冲区指针 sizeof(BULK_TRANSFER_CONTROL), // 输入数据缓冲区长度 pbuf, // 输出数据缓冲区指针 FIFO_LEN, // 输出数据缓冲区长度 &nBytes, // 输出数据实际长度 NULL // 重叠操作结构指针 ); //bResult=ReadFile(hDevice,Buf,len,&rCount,NULL); if(bResult==0) { return 0; } return nBytes; } else { return 0; } } |
|
6楼#
发布于:2008-07-22 15:04
引用第3楼summerfruit于2008-07-22 14:38发表的 : 多谢指点。 正像你说的,我读的这个线程挂起(对驱动理解不深),随之导致主线程也不动作了。(做这个时,我真的感觉到,其实本没有多线程,所谓的多线程是时间片轮流而已~) 我正想在驱动中寻找解决方法,不让它pengding,读不到数据立即返回0(不等待),这样读线程就不至于影响主线程了。不知道各位朋友有高招没有。 其实我发现,很多使用USB与设备通信的软件也存在这个问题,比如我使用的DSP仿真器,经常出现不响应挂起的情况。此时拔掉USB就可以正常响应了。 还请各位继续发表高见。我对驱动不了解,正在学习中…… |
|
驱动小牛
|
7楼#
发布于:2008-07-22 15:39
创建一个线程,死循环读数据放到Buffer中
================ 我的理解,不知道对否: 如果原有驱动没有实现异步,那 .... USB驱动中要实现异步读取就有点麻烦了,USB驱动中开两个线程一读一写,没有状况发生就在KeWaitforSingleObject(或Muti),读取是设置较短的超时。 应用层也要改改,开线程使用WaiforSingleObject等,没有状况不读,有了状况SetEvent,开始读。 |
8楼#
发布于:2008-07-22 15:54
引用第7楼zhoujiamurong于2008-07-22 15:39发表的 : 谢谢再次指导! 有道理,给超时设短点,如果是毫秒级,估计程序应该有一些改善。 USB实现异步…… 现在我还不会,边学习边改驱动试试。 我的上位机程序中,可以采样串口或USB与设备通信,串口通信慢,但是程序反应很快;USB很强劲,但带来的是程序返回缓慢,虽然要的大量数据已经收到,可就是操作太不爽。故想在驱动中寻求突破口。继续学习…… |
|
9楼#
发布于:2008-07-22 17:40
按照你的想法,其实我认为不需要在驱动里面设置线程,只要在应用程序里面设置线程就可以了。这个线程就是读数据,读不到就一直pending都可以啊。
|
|
10楼#
发布于:2008-07-23 08:30
关键是,新创建的线程一挂起,整个程序都无响应……
|
|
11楼#
发布于:2008-08-01 11:31
ezusb.sys驱动不支持异步方式,在应用层只能用多线程方式。
如果上行数据够快,还应该开多个线程同Pending,这样才不会丢数据。 |
|
12楼#
发布于:2008-08-02 09:52
不知道楼主的如何解决PC端读取数据时程序反应慢(当USB设备没发数据的时候,PC又在读会卡在读函数那里)这个问题我一直没有很好的解决,如果解决了这个问题,弄USB又是一个突破,我也愿意把我之前弄USB一点经验共享出来!之前已经写了 《USB驱动的制作过程与体会》但现在觉得还有很多要注意的问题要解决!!!所以想重新写份更详细的,包括硬件电路和PC上的软件!
|
|
13楼#
发布于:2008-08-06 11:45
引用第9楼summerfruit 于2008-07-22 17:40:39发表的
"应用程序里面设置线程就可以了。这个线程就是读数据,读不到就一直pending都可以啊。" 我也这么想的,不过在软件里怎么实现? |
|
|
14楼#
发布于:2008-08-06 11:52
dyzix 在5楼里的程序代码只是读USB设备数据的,没有启动线程方面的问题,所说的“创建一个线程,死循环读数据放到Buffer中,主循环中处理这些数据。读的时候,如果我的MCU不发数据的话,就等待读取Pending。”想请教下软件部分怎么实现?在这读数据函数里怎么加多线程来处理?
|
|
|