阅读:1205回复:4
主机只能发送却无法接受(usb设备),大家帮帮我吧
我做的是usb转串口的主机端(windows)驱动,设备端是linux,在linnux主机上可以正常的读写,可是到了用我的windows驱动读写设备的时候,只能向设备发送数据,但是无法读回设备的数据,我在驱动中断住看了一下,发现是在发下去读urb以后,一直在等待,(kewaitforsingleobject一直没有返回,)softice变得不正常,屏幕和正常的屏幕混杂在一起。
还有一个问题,就是在写设备的时候,第一次可以把数据都写进去,但是后来(应用程序重齐后)总是第一个urb包的数据写不进去,但是后边的都可以,比如我写70各字节,我的最大包大小为64,那样设备就只能收到6个,前64个都没有。 大家帮帮我吧 |
|
沙发#
发布于:2004-11-10 09:17
向设备写数据的时候,我用bus hound看了一下,发现第一个urb被cancel掉了,这可能导致了写的时候总是少前64个字节,可是我没有设置cancel啊,可能是什么原因呢?
|
|
板凳#
发布于:2004-11-10 17:22
我的一点经验:
你的第一个问题是终端接收不到数据,一个容易犯的错误是没有 设置终端的COM口参数,如传输速率,校验位,起始位等。这样终端接受不到数据,当然只有等待。 第二个容易犯的错误是主机与终端的传输速率设置不匹配,USB断口的传输速率快,串口的传输速率慢,MCU的一个作用就是缓冲。 你的第二个问题应该和第一个问题是一个道理,主机发送数据有乱码,程序对端口的默认设置是default,你要把它改成具体的传输速率才行。 在哪里改就不要再问了?自己钻研钻研吧。 |
|
地板#
发布于:2004-11-12 12:36
谢谢大侠的回答,可是我的第一个问题是主机无法读回来数据。
我的第二个问题解决了,原因是我在应用程序关闭的时候把所有的pipes都给abort掉了,结果导致了写不下去前64各字节。 可是第一个问题,就是读不回来的问题,还是没有解决,现在发现一直在等待,并且我要打印urb的执行状态的时候,根本这一句话就没有执行似的,因为屏幕上什末也没有,看一下urb的状态,一直是40000001,根本没有这个状态,根据usbdi.h中定义的urb 状态。 这是什末问题呢?? 我试了设置船口也没有用。 NTSTATUS UsbRead( IN PDEVICE_OBJECT deviceObject,PIRP Irp) { NTSTATUS status = STATUS_SUCCESS; USBD_STATUS urbstatus; PDEVICE_OBJECT LowerdeviceObject; PDEVICE_EXTENSION deviceExtension =(PDEVICE_EXTENSION)deviceObject->DeviceExtension; PIO_STACK_LOCATION nextStack; PIO_STACK_LOCATION CurrentStack = IoGetCurrentIrpStackLocation(Irp); PURB urb = NULL; UCHAR readbuf[65]; for(int j= 0;j<64;j++) {readbuf[j] = 0x55;} ULONG uFlags; PIRP irp; KEVENT Event; ULONG ChunkSize,UsedSize; LONG TotalLength; UsedSize = 0; ChunkSize = 64;//max transfer size. TotalLength = CurrentStack->Parameters.Read.Length; // UCHAR DataBuffer[65];//max transfer size is 64 PUCHAR pDataBuffer;//max transfer size is 64 pDataBuffer =(PUCHAR)ExAllocatePool(NonPagedPool,TotalLength ); // pDataBuffer =(PUCHAR) Irp->AssociatedIrp.SystemBuffer; LowerdeviceObject = deviceExtension->pLowerDevice; while(TotalLength>0) { urb = (PURB) ExAllocatePool( NonPagedPool,sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER) ); if( NULL == urb ) { status = STATUS_INSUFFICIENT_RESOURCES; return status; } uFlags = USBD_TRANSFER_DIRECTION_IN|USBD_SHORT_TRANSFER_OK; if(TotalLength<ChunkSize) { ChunkSize = TotalLength; } UsbBuildInterruptOrBulkTransferRequest(urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER ), deviceExtension->UsbReadPipes->PipeHandle, readbuf, NULL, 64, uFlags, NULL); irp = IoAllocateIrp(deviceObject->StackSize+1, FALSE); // Internal control argument set as URB nextStack = IoGetNextIrpStackLocation(irp); // Get Current IO stack location nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; nextStack->Parameters.DeviceIoControl.IoControlCode= IOCTL_INTERNAL_USB_SUBMIT_URB; nextStack->Parameters.Others.Argument1 = (PVOID)urb; KeInitializeEvent(&Event,NotificationEvent,FALSE); IoSetCompletionRoutine( irp, ReadWriteCompletion, &Event, TRUE, TRUE, TRUE ); status = IoCallDriver( deviceExtension->pLowerDevice,irp); if( !NT_SUCCESS(status) ) { ExFreePool(urb); return status; } urbstatus = USBD_STATUS(&urb); PLARGE_INTEGER pTimeout; ULONGLONG Timeout100; Timeout100 = -10000*200;//500ms pTimeout = PLARGE_INTEGER(&Timeout100) ; if(status ==STATUS_PENDING) { status = KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,pTimeout);//这里一直返回超时,如果我一直等的话,程序就死了,softice也跳出来了。 KdPrint((" read urb status is %8x"),urbstatus); //status = KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); //KdPrint(("read urb status is %8x"),urbstatus); } ExFreePool(urb); IoFreeIrp(irp); for(int i=0;i<ChunkSize;i++) { pDataBuffer[UsedSize] = readbuf; UsedSize++; } TotalLength=TotalLength-UsedSize; } RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,pDataBuffer,UsedSize ); ExFreePool(pDataBuffer ); return status; } NTSTATUS ReadWriteCompletion( PDEVICE_OBJECT DeviceObject,PIRP pIrp,PVOID Context ) { PKEVENT event = (PKEVENT)Context; // Set the input event KeSetEvent(event, 1, FALSE); // Flag this call is not immediately followed by wait. return STATUS_MORE_PROCESSING_REQUIRED; } |
|
地下室#
发布于:2004-12-19 11:05
if(status ==STATUS_PENDING)
{ status = KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,pTimeout);//这里一直返回超时,如果我一直等的话,程序就死了,softice也跳出来了。 KdPrint((" read urb status is %8x"),urbstatus); //status = KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); //KdPrint(("read urb status is %8x"),urbstatus); } 某些事件是使用Microsoft Windows时的公共部分,它仍然可能会对调试应用程序造成潜在的问题。重要的是在于知道这些特殊问题,这样就不至于把调试过程搞得混乱不堪。这段程序是对等待状态的处理程序,主要是调用KeWaitForSingleObject函数进行故障处理。建议你到vc的网站上去查KeWaitForSingleObject函数的用法。 第二种可能是,你的调试过程有问题。程序执行时,可能在执行这段代码之前进入到其他的分支去了,而你调试过程中没有跳转,直接顺序调试下面的错误处理代码了。建议你画出调试程序的流程图,重新进行调试。 |
|