shlei20
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2003-02-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1313回复:2

讨论bulk数据传输问题。

楼主#
更多 发布于:2002-05-31 14:55
 
 想传输1k左右的数据,通过bulk方式传输。自定义IOCTL码实现,

那么,我在编驱动里要注意什么?  
LIUTANG
驱动大牛
驱动大牛
  • 注册日期2001-03-30
  • 最后登录2020-12-27
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望58点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-05-31 21:50
没什么要注意的,无非就是在你那个IOCTL处理函数里加入从BULK口读或写数据的程序,。
shlei20
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2003-02-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-06-01 09:11
自定义ioctls
// Perform an IN transfer over the specified bulk or interrupt pipe.
//
// lpInBuffer: BULK_TRANSFER_CONTROL stucture specifying the pipe number to read from
// nInBufferSize: sizeof(BULK_TRANSFER_CONTROL)
// lpOutBuffer: Buffer to hold data read from the device.  
// nOutputBufferSize: size of lpOutBuffer.  This parameter determines
//    the size of the USB transfer.
// lpBytesReturned: actual number of bytes read
//
#define IOCTL_EVK_BULK_READ     CTL_CODE(FILE_DEVICE_UNKNOWN,\\
                                   IOCTL_INDEX+19,\\
METHOD_OUT_DIRECT,\\
FILE_ANY_ACCESS)



//
// Perform an OUT transfer over the specified bulk or interrupt pipe.
//
// lpInBuffer: BULK_TRANSFER_CONTROL stucture specifying the pipe number to write to
// nInBufferSize: sizeof(BULK_TRANSFER_CONTROL)
// lpOutBuffer: Buffer of data to write to the device
// nOutputBufferSize: size of lpOutBuffer.  This parameter determines
//    the size of the USB transfer.
// lpBytesReturned: actual number of bytes written
//
#define IOCTL_EVK_BULK_WRITE    CTL_CODE(FILE_DEVICE_UNKNOWN,\\
                                        IOCTL_INDEX+20,\\
                                   METHOD_IN_DIRECT,\\
FILE_ANY_ACCESS)





NTSTATUS
YH_Read_Write(IN PDEVICE_OBJECT fdo,
 IN PIRP           Irp)
{

   PDEVICE_EXTENSION         pdx=fdo->DeviceExtension;
   PIO_STACK_LOCATION        irpStack=IoGetCurrentIrpStackLocation(Irp);
   NTSTATUS                  ntStatus=STATUS_SUCCESS;
   PBULK_TRANSFER_CONTROL    bulkControl=(PBULK_TRANSFER_CONTROL)Irp->AssociatedIrp.SystemBuffer;
   ULONG                     bufferLength=irpStack->Parameters.DeviceIoControl.OutputBufferLength;
   PURB                      urb=NULL;
   ULONG                     urbSize=0;
   ULONG                     transferFlags=0;

   NTSTATUS                  status;

   PUSBD_INTERFACE_INFORMATION    interfaceInfo=NULL;
   PUSBD_PIPE_INFORMATION         pipeInfo=NULL;
   USBD_PIPE_HANDLE               pipeHandle=NULL;

   Evk_KdPrint((\"Enter YH_Read_Write\\n\"));

   //valify the selected pipe is valid and get a handle to it.
   //if anything is wrong ,return an error

   interfaceInfo=pdx->Interface;
   if(!interfaceInfo)
   {
  Evk_KdPrint((\"YH_Read_Write() has no interface info -exiting\"));
  return STATUS_UNSUCCESSFUL;
   }

   if(bulkControl->pipeNum>interfaceInfo->NumberOfPipes)
   {
  Evk_KdPrint((\"YH_Read_Write() invalid pipe\"));
  return STATUS_INVALID_PARAMETER;
   }

   pipeInfo=&(interfaceInfo->Pipes[bulkControl->pipeNum]);

   if(!((pipeInfo->PipeType==UsbdPipeTypeBulk)||
   (pipeInfo->PipeType==UsbdPipeTypeInterrupt)))
   {
  Evk_KdPrint((\"YH_Read_Write() invalid pipe - Exiting\\n\"));
  return STATUS_INVALID_PARAMETER;
   }

   pipeHandle=pipeInfo->PipeHandle;

  
    
   if(!pipeHandle)
   {
Evk_KdPrint((\"YH_Read_Write() invalid pipe-Exiting\\n\"));
return STATUS_UNSUCCESSFUL;
   }
   //////


   if(!NT_SUCCESS(HResetPipe(fdo,pipeHandle)))
     HResetDevice(fdo);

   //   Evk_KdPrint((\"Failed to reset pipe\"));
   //  HResetDevice(fdo);
    if(bufferLength>pipeInfo->MaximumPacketSize)
     {
Evk_KdPrint((\"too long to transfer\\n\"));
       return STATUS_INVALID_PARAMETER;
     }

   //
   //allocate and fill in the usb request
   //
   urbSize=sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);

   urb=ExAllocatePool(NonPagedPool,urbSize);

   if(!urb)
   {
  Evk_KdPrint((\"YH_Read_Write() unable to allocate urb--exiting\\n\"));
  return STATUS_NO_MEMORY;
   }

   transferFlags=USBD_SHORT_TRANSFER_OK;

   //
   //get direction info from endpoints address
   //
 if(USB_ENDPOINT_DIRECTION_IN(pipeInfo->EndpointAddress))
 { transferFlags|=USBD_TRANSFER_DIRECTION_IN;
   Evk_KdPrint((\"Read From Device\\n\"));
 }
 else
 { Evk_KdPrint((\"Write to Device\\n\")); }

  UsbBuildInterruptOrBulkTransferRequest(urb,
                                     (USHORT) urbSize,
 pipeHandle,        //pipeHandle
 NULL,              //transferBuffer
 Irp->MdlAddress,   //transferBufferMDL
 bufferLength,      //transferBufferLength
 transferFlags,     //transferFlags
 NULL               //link
 );

   //call the USB stack
   ntStatus=Evk_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))
  {
  Irp->IoStatus.Information=urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  Evk_KdPrint((\"Successfully transfered 0x%x bytes\\n\",Irp->IoStatus.Information));
 
   }

  
   // free the URB
   //
   ExFreePool(urb);
  
   return ntStatus;
 
}



我在程序里是这样实现的,但在实际的数据传送过程中,很不稳定,
有时能够成功传输,有时告诉我bus driver 处理urb失败,所以,现在很是困惑啊! 有谁能够给我指点啊?

游客

返回顶部