IoManager
驱动牛犊
驱动牛犊
  • 注册日期2007-05-04
  • 最后登录2008-12-29
  • 粉丝1
  • 关注1
  • 积分185分
  • 威望35点
  • 贡献值0点
  • 好评度30点
  • 原创分0分
  • 专家分0分
阅读:2000回复:13

Bulk 传输问题:写数据OK,读数据:没反应。求解!

楼主#
更多 发布于:2007-05-23 11:39
高手给小弟指点一下:
小弟的USB设备枚举成功,可以读出各种描述符 。。。
端点1:OU T BULK  64B,接口芯片PDIUSBD12
向设备写数据没有问题。
端点1:IN  BULK  64B
从设备读数据:没反应,用户程序一直处于等待中。。。
小弟用softice跟踪了一下。。。
读数据时:URB放到USB总线上就没反映了。
写数据时:URB放到USB总线上很快就返回了。。。
问题大概就是这样。

NTSTATUS  CollData_Bulk_Transfer(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
NTSTATUS  ntStatus;
PURB      PUrb=NULL;
USHORT    SizeofUrb =0;
ULONG     TransferFlag=0;
ULONG     BufferLength=0;
PUSBD_INTERFACE_INFORMATION   InterfaceInfo =NULL;
PUSBD_PIPE_INFORMATION   PipeInfo=NULL;
USBD_PIPE_HANDLE    PipeHandle =NULL;
PDEVICE_EXTENSION  PDevExn =(PDEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION  IrpStack = NULL;
PBULK_TRANSFER_CONTROL  PBulkCtl = NULL;

IrpStack = IoGetCurrentIrpStackLocation(Irp);
PBulkCtl = (PBULK_TRANSFER_CONTROL)Irp->AssociatedIrp.SystemBuffer;
BufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

InterfaceInfo = PDevExn->InterfaceInfo;          //以下对配置信息进行校验
if (!InterfaceInfo)
    return STATUS_UNSUCCESSFUL;
if (PBulkCtl->pipeNum > InterfaceInfo->NumberOfPipes)
    return STATUS_INVALID_PARAMETER;
PipeInfo =&(InterfaceInfo->Pipes[PBulkCtl->pipeNum]);
if((PipeInfo->PipeType!=UsbdPipeTypeBulk) &&(PipeInfo->PipeType!=UsbdPipeTypeInterrupt))
    return STATUS_INVALID_PARAMETER;
 PipeHandle = PipeInfo->PipeHandle;
if (!PipeHandle)
       return STATUS_UNSUCCESSFUL;
if (BufferLength >PipeInfo->MaximumTransferSize)
      return STATUS_INVALID_PARAMETER;

SizeofUrb = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
PUrb = ExAllocatePool(NonPagedPool,SizeofUrb);
if (!PUrb)
     return STATUS_NO_MEMORY;

TransferFlag = USBD_SHORT_TRANSFER_OK;
if (USB_ENDPOINT_DIRECTION_IN(PipeInfo->EndpointAddress))
    TransferFlag |=USBD_TRANSFER_DIRECTION_IN;
UsbBuildInterruptOrBulkTransferRequest(PUrb,
                                           SizeofUrb,
                        Pipe Handle,
                      NULL,
                 Irp->MdlAddress,
            BufferLength,
            TransferFlag,
             NULL);
ntStatus = CallUSBDI(fdo,PUrb);
if (NT_SUCCESS(ntStatus))
    ->IoStatus.Information = PUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
ExFreePool(PUrb);
return ntStatus;                                                  
    }
//程序参照《USB2.0原理与工程开发》

最新喜欢:

wingmanwingma...
IoManager
驱动牛犊
驱动牛犊
  • 注册日期2007-05-04
  • 最后登录2008-12-29
  • 粉丝1
  • 关注1
  • 积分185分
  • 威望35点
  • 贡献值0点
  • 好评度30点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-05-24 17:51
谢谢上面兄弟们了。
两位兄弟都认为USB设备没有返回给驱动程序数据,导致驱动一直处于等待中。事实就是这样的!!
当程序执行到 ntStatus = CallUSBDI(fdo,PUrb); //将URB发送到总线上 语句时,程序就不在往下执行了。。。它一直处于等待中,也就是等待USB设备向主机发送数据。
如果一切正常的话,当程序执行到上述语句时,令牌OUT会使接口芯片向单片机发送一个中断,告诉单片机向接口芯片缓冲区中写数据,然后令牌IN会带走这些数据。事实是,这个中断没有发生!
我想可能是我的驱动程序有问题,我把DDK自带的例子(bulkusb)编译一下,同样是这个毛病;另外可能是单片机固件的问题,固件又重新查了一边,也没看出哪里异常。再说如果有问题,那么写数据也应该有问题啊!
就这样,每当想到一个可能的问题,马上又会想到它的矛盾面。
。。痛苦啊。
我记得我装DriverStdio时,也是痛苦了一阵,当时一运行softice机器就死机。我就不明白,以为肯定是哪里设置不对。在网上查资料,发帖子。还是没解决。最后没办法把系统重装了一下,第一个装的软件就是DriverStdio,奇迹发生了,softice可以运行。最后装卡巴斯基时,机器又死机了。这时我明白,这两个软件是相冲突的。
IoManager
驱动牛犊
驱动牛犊
  • 注册日期2007-05-04
  • 最后登录2008-12-29
  • 粉丝1
  • 关注1
  • 积分185分
  • 威望35点
  • 贡献值0点
  • 好评度30点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-05-25 09:42
IoManager
驱动牛犊
驱动牛犊
  • 注册日期2007-05-04
  • 最后登录2008-12-29
  • 粉丝1
  • 关注1
  • 积分185分
  • 威望35点
  • 贡献值0点
  • 好评度30点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-05-30 17:15
问题的答案是:PDIUSBD12在收到 IN 之前数据缓冲区必须有效。
所以必须在OUT端点对IN 端点进行更新。
IoManager
驱动牛犊
驱动牛犊
  • 注册日期2007-05-04
  • 最后登录2008-12-29
  • 粉丝1
  • 关注1
  • 积分185分
  • 威望35点
  • 贡献值0点
  • 好评度30点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-06-28 22:38
rayyang2000 兄弟说得对,不一定要第一个IN之前把数据写入缓冲区。但如果要使D12响应IN,则必须要更新其数据缓冲区,否则D12不会对MCU发出中断
IoManager
驱动牛犊
驱动牛犊
  • 注册日期2007-05-04
  • 最后登录2008-12-29
  • 粉丝1
  • 关注1
  • 积分185分
  • 威望35点
  • 贡献值0点
  • 好评度30点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-06-30 00:51
onizuka2070:接口芯片是PDIUSBD12吗?我的接口芯片是这个。
如果方便就把中断服务函数放到上面。让我们大家分析一下。
要不你这样试试:
   在你受到OUT时,刷新数据区。
IoManager
驱动牛犊
驱动牛犊
  • 注册日期2007-05-04
  • 最后登录2008-12-29
  • 粉丝1
  • 关注1
  • 积分185分
  • 威望35点
  • 贡献值0点
  • 好评度30点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-07-01 00:43
USB接口芯片肯定有好几个端点,每个端点肯定有数据缓冲区;
刷新数据就是用USB接口芯片的命令去更新相应端点的数据缓冲区,告诉USB接口芯片数据准备好了。
游客

返回顶部