阅读:902回复:4
swf2003.急救啊。帮我看看
SWF2003:
您好! 我的应用程序如下: ULONG ulLength = 8*1024*1024; unsigned char *tempbuffer=(unsigned char *)malloc(ulLength); bResult = DeviceIoControl (hDevice, ioctl_val, &bulkControl, sizeof (BULK_TRANSFER_CONTROL), tempbuffer, ulLength ,//length (unsigned long *)&nBytes, NULL); 驱动里的程序如下: NTSTATUS Ezusb_Read_Write( IN PDEVICE_OBJECT fdo, IN PIRP Irp ) { PDEVICE_EXTENSION pdx = fdo->DeviceExtension; NTSTATUS ntStatus; PIO_STACK_LOCATION irp=StackIoGetCurrentIrpStackLocation (Irp); PBULK_TRANSFER_CONTROL bulkControl = (PBULK_TRANSFER_CONTROL)Irp->AssociatedIrp.SystemBuffer; int i; ULONG bufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; PURB urb = NULL; ULONG urbSize = 0; ULONG transferFlags = 0; ULONG Length = MmGetMdlByteCount(Irp->MdlAddress); //addin PUSBD_INTERFACE_INFORMATION interfaceInfo = NULL; BYTE* pMdlAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);//addin ULONG singleTransferLength = 64*1024;//addin PUSBD_PIPE_INFORMATION pipeInfo = NULL; USBD_PIPE_HANDLE pipeHandle = NULL; PVOID databuffer=ExAllocatePool(NonPagedPool,64*1024); Ezusb_KdPrint((\"OutputBufferLength==%d\\n\"),irpStack->Parameters.DeviceIoControl.OutputBufferLength); Ezusb_KdPrint((\"enter Ezusb_Read_Write()\\n\")); Ezusb_KdPrint((\"bulkControl->pipeNum=%d\\n\",bulkControl->pipeNum)); Ezusb_KdPrint((\"Length=%d\\n\",Length)); // // verify that the selected pipe is valid, and get a handle to it. If anything // is wrong, return an error // interfaceInfo = pdx->Interface; if (!interfaceInfo) { Ezusb_KdPrint((\"Ezusb_Read_Write() no interface info - Exiting\\n\")); return STATUS_UNSUCCESSFUL; } Ezusb_KdPrint((\"interfaceInfo->NumberOfPipes=%d\\n\",interfaceInfo->NumberOfPipes)); if (bulkControl->pipeNum > interfaceInfo->NumberOfPipes) { Ezusb_KdPrint((\"pipeNum Ezusb_Read_Write() invalid pipe - Exiting\\n\")); return STATUS_INVALID_PARAMETER; } pipeInfo = &(interfaceInfo->Pipes[bulkControl->pipeNum]); if (!((pipeInfo->PipeType == UsbdPipeTypeBulk) || (pipeInfo->PipeType == UsbdPipeTypeInterrupt))) { Ezusb_KdPrint((\" PipeType Ezusb_Read_Write() invalid pipe - Exiting\\n\")); return STATUS_INVALID_PARAMETER; } pipeHandle = pipeInfo->PipeHandle; if (!pipeHandle) { Ezusb_KdPrint((\"pipeHandle Ezusb_Read_Write() invalid pipe - Exiting\\n\")); return STATUS_UNSUCCESSFUL; } Ezusb_KdPrint((\"pipe\'s MaximumTransferSize==%d\\n\"),pipeInfo->MaximumTransferSize); if (bufferLength > pipeInfo->MaximumTransferSize) { Ezusb_KdPrint((\"Ezusb_Read_Write() invalid transfer size - Exiting\\n\")); return STATUS_INVALID_PARAMETER; } // // allocate and fill in the Usb request (URB) // RtlCopyMemory // urbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); urb = ExAllocatePool(NonPagedPool,urbSize); if (!urb) { Ezusb_KdPrint((\"Ezusb_Read_Write() unable to alloc URB - Exiting\\n\")); return STATUS_NO_MEMORY; } // PVOID ioBuffer = Irp->AssociatedIrp.SystemBuffer; Ezusb_KdPrint((\"Irp->MdlAddress bufferLength==%d\\n\"),bufferLength); transferFlags = USBD_SHORT_TRANSFER_OK; // transferFlags = USBD_TRANSFER_DIRECTION_IN; // // get direction info from the endpoint address // if (USB_ENDPOINT_DIRECTION_IN(pipeInfo->EndpointAddress)) transferFlags |= USBD_TRANSFER_DIRECTION_IN; for( i=0; i< 128; i++) { UsbBuildInterruptOrBulkTransferRequest(urb, //ptr to urb (USHORT) urbSize, //size of urb pipeHandle, //usbd pipe handle databuffer, //TransferBuffer NULL //Irp->MdlAddress, //mdl singleTransferLength,//bufferLength, //bufferlength transferFlags, //flags NULL); //link // // Call the USB Stack. // ntStatus = Ezusb_CallUSBD(fdo, urb); // // If the transfer was successful, report the length of the transfer to the // caller by setting IoStatus.Information // if (NT_SUCCESS(ntStatus)) { RtlCopyMemory((pMdlAddress + i*singleTransferLength), databuffer, singleTransferLength); Irp->IoStatus.Information = urb->UrbBulkOrInterruptTransfer.TransferBufferLength; Ezusb_KdPrint((\"Successfully transfered 0x%x bytes\\n\",Irp->IoStatus.Information)); } //然后用UsbBuildInterruptOrBulkTransferRequest()循环读取数据放到ioBuffer中,每次成功返回后都拷贝数据如下: } // // free the URB // ExFreePool(urb); return ntStatus; } 我是依葫芦画瓢,拿您回复帖子的程序改的。我想实现的功能是在应用中开大缓存,把地址传给驱动,然驱动不断循环从设备那读取我要的数据,后拷贝到我的应用缓存中去。这样行吗。 我在调试中发现outputbufferlength的值不是我传来的值,甚至是负数。驱动在if (bufferLength > pipeInfo->MaximumTransferSize)这里就退出了。 并且报错 Ezusb_Read_Write() invalid transfer size - Exiting; 所以下面的我就无法调。 其实我要做的是实时采集数据。就是让驱动一直不停的收数据,您说过可以用两个URB来做。我不知道如何去做。这样做的机制如何实现啊,这是我最想知道的和最困惑的。特向你求救啊。我的邮箱 lioniamhero@yahoo.com.cn |
|
沙发#
发布于:2003-09-25 22:46
有人能指导吗。请高手们留步啊。
|
|
板凳#
发布于:2003-09-29 11:28
记不清楚那个ulLength传到驱动里是OutputBufferLength,还是InputBufferLength,你自己再查一下,好想是前者,你看到那个负值肯定是不对的,正常情况要么是你的ulLength,要么是sizeof (BULK_TRANSFER_CONTROL),负值就说明那个区域是随机值。
因为你的ulLength>MaximumTransferSize,MaximumTransferSize的值是64k-1,因此你必须把那几行去掉才能接着往下走。 |
|
地板#
发布于:2003-09-29 11:44
还有你那个bufferlength最好用如下的方法获得:
ULONG bufferLength = MmGetMdlByteCount(Irp->MdlAddress); 这样肯定是你驱动传进去的那个ulLength 拷贝数据的方法如下: RtlCopyMemory((char *)pMdlAddress + i*SingleTransferLength, databuffer, SingleTransferLength); 另外下面两行要挪出if (NT_SUCCESS(ntStatus)),而且第一行还要改一改,因为Irp->IoStatus.Information里存放的是本次操作的数据量,因此你实际得到多少数据就填多少,比如你实际得到了8m,那么这个值就时8m,然后就是ntStatus返回,不要每循环一次就赋一次值 Irp->IoStatus.Information = urb->UrbBulkOrInterruptTransfer.TransferBufferLength; Ezusb_KdPrint((\"Successfully transfered 0x%x bytes\\n\",Irp->IoStatus.Information)); 另外你还要考虑剩余数据问题,如果你需要的数据并不是64k的倍数,那么循环里就不能全部得到数据了,还要把剩余的部分也得到。 另外说几句泼你冷水的话,这个同步传输即使这样做了,保证不丢数据的速度也不是很高,我用isp1581才1MB/s,用68013可能会快一些,可是你要是要求速度过高的话最根本的方法是在设备方加上缓存,如果不是很高可一像你现在的情况优化驱动和应用程序 最后,我到现在也没搞定我的问题,十分十分的郁闷!!! :( :( :( |
|
地下室#
发布于:2003-09-29 12:40
非常感谢,我在邮件里给你回了。
|
|