阅读:2089回复:10
如何开辟一个线程实现BULK IN的不断的读取USB的数据啊?如何轮询USB设备?
大家好:
我想用驱动在内核里面开一个线程实现BULK IN不断读取数据,然后存到一个队列里面(前提条件是队列有效就能不断的读取,队列满就处于挂起状态),如何实现这样一个线程呢? 可以参考哪些资料呢?谁有这样的例子麻烦发一份啊 ,谢谢了! 简单来讲就是如何在驱动里面轮询USB DEVICE,要求速度尽可能的快和尽量少占用系统的资源。。。。。。。 |
|
沙发#
发布于:2005-07-15 12:45
UsbBuildInterruptOrBulkTransferRequest,不停的调用就可以了,没有数据会自动BLOCK,有就会一直收。至于资源吗,数据多肯定是要费资源的,但BLOCK不浪费资源。
|
|
板凳#
发布于:2005-07-17 07:39
楼上老哥的意思是做开一个线程一直调用
void thread_read() { while(1){ do sth(); UsbBuildInterruptOrBulkTransferRequest(...); do sth(); } } 吗?如果处于阻塞状态,在没有收到数据的情况下,那么USB总线上还会一直有“IN”这个令牌包产生吗?我的意思是USB总线上要一直有“IN”的令牌包产生,下面固件有数据产生的时候主机就靠这个令牌包把数据带上来,但是数据的产生是随机的,所以希望用轮训设备来完成。直到用户停止这个设备或者拔掉这个设备。想必大家也遇到过这样的问题,麻烦各位帮我一把! |
|
地板#
发布于:2005-07-18 09:08
驱动发一个请求,in令牌会出现出现一次,只有fireware准备好数据,并把RDY置位的时候,该函数才返回,这完全能实现你的需求呀。
|
|
地下室#
发布于:2005-07-19 09:20
有人建议用IoSetCompleteRoutine(),但是我不知道如何使用,也不知道能不能达到至少30MBYTE/s的速度。请问有人用过这个函数吗?请多多赐教啊。
|
|
5楼#
发布于:2005-07-19 09:52
看看ddk里bulkusb的例子,就是这么做的。
|
|
6楼#
发布于:2005-07-21 19:31
感谢老兄回答!
ASMYSY老兄的意思是当FIREMWARE没有准备好数据的时候 void thread_read() { while(1){ do sth(); UsbBuildInterruptOrBulkTransferRequest(...); do sth(); } } 线程里面的UsbBuildInterruptOrBulkTransferRequest(...)会自动把thread_read()线程阻塞住吗? 阻塞后还会发起一个请求在USB总线上产生IN的令牌吗? |
|
7楼#
发布于:2005-07-22 10:05
期待中……
|
|
8楼#
发布于:2005-07-25 20:28
UsbBuildInterruptOrBulkTransferRequest只是个宏,就用来build urb的,怎么会发送什么请求?!
|
|
9楼#
发布于:2005-07-26 09:02
下面是引用arthurtu于2005-07-25 20:28发表的: build了当然要发出去。 用这个函数发 NTSTATUS SendAwaitUrb(PIrDevice Adapter, PURB pUrb) { PIRP pIrp; KEVENT event; NTSTATUS status; IO_STATUS_BLOCK iostatus; PIO_STACK_LOCATION stack; // DBGPRINT (" ==> SendAwaitUrb().\n"); KeInitializeEvent (&event, NotificationEvent, FALSE); pIrp = IoBuildDeviceIoControlRequest ( IOCTL_INTERNAL_USB_SUBMIT_URB, Adapter->NextDeviceObject, NULL, 0, NULL, 0, TRUE, &event, &iostatus); stack = IoGetNextIrpStackLocation(pIrp); stack->Parameters.Others.Argument1 = (PVOID) pUrb; status = IoCallDriver(Adapter->NextDeviceObject, pIrp); // DBGPRINTSEND("IoCallDriver() = 0x%8.8X.\n", status); // DBGPRINTSEND("URB_STATUS(urb) = 0x%8.8X.\n",URB_STATUS(pUrb)); if (status == STATUS_PENDING) { // DBGPRINTSEND("......\n"); KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL); status = iostatus.Status; } // DBGPRINTSEND("iostatus.Status = 0x%8.8X.\n", iostatus.Status); // DBGPRINTSEND("iostatus.Information = 0x%8.8X.\n", iostatus.Information ); // DBGPRINTSEND("status = 0x%8.8X.\n\n", status ); return status; } 如果还不明白,我可以再贴更多的代码。 |
|
10楼#
发布于:2005-07-28 19:00
??????没人讨论了?
|
|