xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1205回复:4

主机只能发送却无法接受(usb设备),大家帮帮我吧

楼主#
更多 发布于:2004-11-09 20:08
我做的是usb转串口的主机端(windows)驱动,设备端是linux,在linnux主机上可以正常的读写,可是到了用我的windows驱动读写设备的时候,只能向设备发送数据,但是无法读回设备的数据,我在驱动中断住看了一下,发现是在发下去读urb以后,一直在等待,(kewaitforsingleobject一直没有返回,)softice变得不正常,屏幕和正常的屏幕混杂在一起。
还有一个问题,就是在写设备的时候,第一次可以把数据都写进去,但是后来(应用程序重齐后)总是第一个urb包的数据写不进去,但是后边的都可以,比如我写70各字节,我的最大包大小为64,那样设备就只能收到6个,前64个都没有。
大家帮帮我吧
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-11-10 09:17
向设备写数据的时候,我用bus hound看了一下,发现第一个urb被cancel掉了,这可能导致了写的时候总是少前64个字节,可是我没有设置cancel啊,可能是什么原因呢?
ctxez
驱动牛犊
驱动牛犊
  • 注册日期2004-10-31
  • 最后登录2006-07-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-11-10 17:22
我的一点经验:
    你的第一个问题是终端接收不到数据,一个容易犯的错误是没有
设置终端的COM口参数,如传输速率,校验位,起始位等。这样终端接受不到数据,当然只有等待。
    第二个容易犯的错误是主机与终端的传输速率设置不匹配,USB断口的传输速率快,串口的传输速率慢,MCU的一个作用就是缓冲。
    你的第二个问题应该和第一个问题是一个道理,主机发送数据有乱码,程序对端口的默认设置是default,你要把它改成具体的传输速率才行。
    在哪里改就不要再问了?自己钻研钻研吧。
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于: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;
}

 
ctxez
驱动牛犊
驱动牛犊
  • 注册日期2004-10-31
  • 最后登录2006-07-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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函数的用法。
第二种可能是,你的调试过程有问题。程序执行时,可能在执行这段代码之前进入到其他的分支去了,而你调试过程中没有跳转,直接顺序调试下面的错误处理代码了。建议你画出调试程序的流程图,重新进行调试。
游客

返回顶部