lioniamhero
驱动小牛
驱动小牛
  • 注册日期2003-05-31
  • 最后登录2005-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:902回复:4

swf2003.急救啊。帮我看看

楼主#
更多 发布于:2003-09-25 12:52
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
lioniamhero
驱动小牛
驱动小牛
  • 注册日期2003-05-31
  • 最后登录2005-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-09-25 22:46
有人能指导吗。请高手们留步啊。
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-09-29 11:28
记不清楚那个ulLength传到驱动里是OutputBufferLength,还是InputBufferLength,你自己再查一下,好想是前者,你看到那个负值肯定是不对的,正常情况要么是你的ulLength,要么是sizeof (BULK_TRANSFER_CONTROL),负值就说明那个区域是随机值。

因为你的ulLength>MaximumTransferSize,MaximumTransferSize的值是64k-1,因此你必须把那几行去掉才能接着往下走。
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
地板#
发布于: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可能会快一些,可是你要是要求速度过高的话最根本的方法是在设备方加上缓存,如果不是很高可一像你现在的情况优化驱动和应用程序

最后,我到现在也没搞定我的问题,十分十分的郁闷!!!
 :( :( :(
lioniamhero
驱动小牛
驱动小牛
  • 注册日期2003-05-31
  • 最后登录2005-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-09-29 12:40
非常感谢,我在邮件里给你回了。
游客

返回顶部