阅读:1924回复:0
请教:在提高usb驱动传输率时遇到的问题!
下面是本人在提高usb驱动传输率时遇到的问题!请高手指教!!!本人不胜感激。
目前的情况是这样的,firmware、user mode application部分已经完全掌握,minidriver也已经大部分掌握,整个系统运行正常,从user mode application发送下去的数据都能正确地送到试验板上。 现在所碰到的问题主要是在minidriver上,我当前的思路是,在app中定义的用户态缓冲区为64字节长,每次minidriver接收到app传送下来的irp,并将用户态缓冲区中的数据复制到核心态的mdl中,然后再将urb发送到下层驱动完成一次64字节的传送,如此循环直到将数据发送完成。但是,这样的数据传输率很不能令人满意,仅达到20k Bytes/sec左右。为此,希望能进一步提高传送速率,我进一步改进minidriver中的方法。即是,首先将app中的发送缓冲区长度增达其长度大于64字节小于64k Bytes(单个管道一次所能传送的最大长度),然后minidriver将接收到的上述数据拆分成64字节的irp放入队列中,采用嵌套方式将这些包发送出去(此思路是参考ddk例程)。 下面是上述思路的完整代码,在SOFT-ICE下跟踪到下面这个函数时计算机就自动重起了,我一直找不到原因,望指教,谢谢! UsbBuildInterruptOrBulkTransferRequest(ctx->urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), hpipe, NULL, mdl, seglen, urbflags, NULL); 下面是我的函数: NTSTATUS USBsys_StagedReadWrite( IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN BOOLEAN Read ) { NTSTATUS ntStatus = STATUS_SUCCESS,status; NTSTATUS resetPipeStatus; PFILE_OBJECT fileObject; PIO_STACK_LOCATION irpStack, nextStack,stack; PURB urb; PIRP irp; PMDL mdl; PULONG va; CHAR stackSize; KIRQL OldIrql; BOOLEAN fRes; NTSTATUS waitStatus; ULONG i, nIrps = 0, totalLength = 0, totalIrpsNeeded, used,length,seglen; PUSBD_PIPE_INFORMATION pipeHandle = NULL; PDEVICE_EXTENSION pdx,deviceExtension = fdo; PULONG pCon = NULL; ULONG ChunkSize = 64; ULONG arraySize; PUDK_RW_CONTEXT context = NULL; BOOLEAN read; PRWCONTEXT ctx; ULONG urbflags; LONG haderr; USBD_PIPE_HANDLE hpipe; KdPrint (("enter BulkUsb_StagedReadWrite()\n")); pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) return CompleteRequest(Irp, status, 0); stack = IoGetCurrentIrpStackLocation(Irp); read = stack->MajorFunction == IRP_MJ_READ; fileObject = stack->FileObject; pipeHandle = fileObject->FsContext; hpipe = pipeHandle->PipeHandle; if (read) haderr = InterlockedExchange(&pdx->inerror, 0); else haderr = InterlockedExchange(&pdx->outerror, 0); if (haderr && !NT_SUCCESS(ResetPipe(fdo, hpipe))) ResetDevice(fdo); ctx = (PRWCONTEXT) ExAllocatePool(NonPagedPool, sizeof(RWCONTEXT)); if (!ctx) { KdPrint((" - Can't allocate memory for context structure\n")); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES, 0); } RtlZeroMemory(ctx, sizeof(RWCONTEXT)); length = Irp->MdlAddress ? MmGetMdlByteCount(Irp->MdlAddress) : 0; if (!length) { // zero-length read IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return CompleteRequest(Irp, STATUS_SUCCESS, 0); } // zero-length read va = (PULONG) MmGetMdlVirtualAddress(Irp->MdlAddress); urbflags = USBD_SHORT_TRANSFER_OK | (read ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT); seglen = length; mdl = IoAllocateMdl((PVOID) va, length, FALSE, FALSE, NULL); if (!mdl) { // can't allocate MDL KdPrint((" - Can't allocate memory for MDL\n")); ExFreePool(ctx); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES, 0); } // can't allocate MDL IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) va, seglen); =〉 运行到此处时,计算机重起(是否是因为在核心状态操作内存引起的???如果是,则原因何在???) UsbBuildInterruptOrBulkTransferRequest(ctx->urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), hpipe, NULL, mdl, seglen, urbflags, NULL); ctx->va = va + seglen; ctx->length = length - seglen; ctx->mdl = mdl; ctx->numxfer = 0; stack = IoGetNextIrpStackLocation(Irp); stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; stack->Parameters.Others.Argument1 = (PVOID)ctx; stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnReadWriteComplete, (PVOID) ctx, TRUE, TRUE, TRUE); IoMarkIrpPending(Irp); status = IoCallDriver(pdx->LowerDeviceObject, Irp); if (!NT_SUCCESS(status) && !NT_SUCCESS(ResetPipe(fdo, hpipe))) ResetDevice(fdo); return STATUS_PENDING; } |
|