打印

TO USB驱动开发的例程问题

[复制链接]
1972|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhuww|  楼主 | 2010-8-18 22:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
人使用Cy7c68013A进行开发,其它例程都已经完成,控制传输找资料已经完成.
只是剩下       DriverObject-> MajorFunction[IRP_MJ_WRITE]   =   Ezusb_Write;       //写入数据
      DriverObject-> MajorFunction[IRP_MJ_READ]   =   Ezusb_Read;           //读取数据


这两个例程没有完成,本人没有写过此类例程,不知如何下手,有知道的朋友告知一下相关的消息也行,谢谢了.
沙发
zhuww|  楼主 | 2010-8-18 22:41 | 只看该作者
NTSTATUS
Ezusb_Read(
        IN   PDEVICE_OBJECT   DeviceObject,
        IN   PIRP                       Irp
        )
{
        PMDL                                       mdl;
        PURB                                       urb;
        ULONG                                     totalLength;
        ULONG                                     stageLength;
        ULONG                                     urbFlags;
        BOOLEAN                                 read;
        NTSTATUS                               ntStatus;
        ULONG_PTR                             virtualAddress;
        PFILE_OBJECT                       fileObject;
        PDEVICE_EXTENSION             deviceExtension;
        PIO_STACK_LOCATION           irpStack;
        PIO_STACK_LOCATION           nextStack;
        PBULKUSB_RW_CONTEXT         rwContext;
        PUSBD_PIPE_INFORMATION   pipeInformation;
PVOID   IoBuffer;


        //
        //   initialize   variables
        //
        urb   =   NULL;
        mdl   =   NULL;
        rwContext   =   NULL;
        totalLength   =   0;
        irpStack   =   IoGetCurrentIrpStackLocation(Irp);
        fileObject   =   irpStack-> FileObject;
        read   =   (irpStack-> MajorFunction   ==   IRP_MJ_READ)   ?   TRUE   :   FALSE;
        deviceExtension   =   (PDEVICE_EXTENSION)   DeviceObject-> DeviceExtension;
        IoBuffer                       =   Irp-> AssociatedIrp.SystemBuffer;

        if(fileObject   &&   fileObject-> FsContext)   {

                pipeInformation   =   fileObject-> FsContext;

                if((UsbdPipeTypeBulk   !=   pipeInformation-> PipeType)   &&
                      (UsbdPipeTypeInterrupt   !=   pipeInformation-> PipeType))   {
                        
                        ntStatus   =   STATUS_INVALID_HANDLE;
                        goto   BulkUsb_DispatchRead_Exit;
                }
        }
        else   {

                ntStatus   =   STATUS_INVALID_HANDLE;
                goto   BulkUsb_DispatchRead_Exit;
        }

        rwContext   =   (PBULKUSB_RW_CONTEXT)
                                ExAllocatePool(NonPagedPool,
                                                              sizeof(BULKUSB_RW_CONTEXT));

        if(rwContext   ==   NULL)   {
               

                ntStatus   =   STATUS_INSUFFICIENT_RESOURCES;
                goto   BulkUsb_DispatchRead_Exit;
        }

        if(Irp-> MdlAddress)   {

                totalLength   =   MmGetMdlByteCount(Irp-> MdlAddress);
        }

        if(totalLength   >   BULKUSB_TEST_BOARD_TRANSFER_BUFFER_SIZE)   {


                ntStatus   =   STATUS_INVALID_PARAMETER;

                ExFreePool(rwContext);

                goto   BulkUsb_DispatchRead_Exit;
        }

        if(totalLength   ==   0)   {


                ntStatus   =   STATUS_SUCCESS;

                ExFreePool(rwContext);

                goto   BulkUsb_DispatchRead_Exit;
        }

        urbFlags   =   USBD_SHORT_TRANSFER_OK;
        virtualAddress   =   (ULONG_PTR)   MmGetMdlVirtualAddress(Irp-> MdlAddress);

        if(read)   {

                urbFlags   |=   USBD_TRANSFER_DIRECTION_IN;
        }
        else   {

                urbFlags   |=   USBD_TRANSFER_DIRECTION_OUT;
        }

        //
        //   the   transfer   request   is   for   totalLength.
        //   we   can   perform   a   max   of   BULKUSB_MAX_TRANSFER_SIZE
        //   in   each   stage.
        //
        if(totalLength   >   BULKUSB_MAX_TRANSFER_SIZE)   {

                stageLength   =   BULKUSB_MAX_TRANSFER_SIZE;
        }
        else   {

                stageLength   =   totalLength;
        }

        mdl   =   IoAllocateMdl((PVOID)   virtualAddress,
                                                totalLength,
                                                FALSE,
                                                FALSE,
                                                NULL);

        if(mdl   ==   NULL)   {
        

                ntStatus   =   STATUS_INSUFFICIENT_RESOURCES;

                ExFreePool(rwContext);

                goto   BulkUsb_DispatchRead_Exit;
        }

        //
        //   map   the   portion   of   user-buffer   described   by   an   mdl   to   another   mdl
        //
        IoBuildPartialMdl(Irp-> MdlAddress,
                                            mdl,
                                            (PVOID)   virtualAddress,
                                            stageLength);

        urb   =   ExAllocatePool(NonPagedPool,
                                                  sizeof(struct   _URB_BULK_OR_INTERRUPT_TRANSFER));

        if(urb   ==   NULL)   {


                ntStatus   =   STATUS_INSUFFICIENT_RESOURCES;

                ExFreePool(rwContext);
                IoFreeMdl(mdl);

                goto   BulkUsb_DispatchRead_Exit;
        }

        UsbBuildInterruptOrBulkTransferRequest(
                                                        urb,
                                                        sizeof(struct   _URB_BULK_OR_INTERRUPT_TRANSFER),
                                                        pipeInformation-> PipeHandle,
                                                        NULL,
                                                        mdl,
                                                        stageLength,
                                                        urbFlags,
                                                        NULL);

        //
        //   set   BULKUSB_RW_CONTEXT   parameters.
        //
        
        rwContext-> Urb                           =   urb;
        rwContext-> Mdl                           =   mdl;
        rwContext-> Length                     =   totalLength   -   stageLength;
        rwContext-> Numxfer                   =   0;
        rwContext-> VirtualAddress     =   virtualAddress   +   stageLength;
        rwContext-> DeviceExtension   =   deviceExtension;

        //
        //   use   the   original   read/write   irp   as   an   internal   device   control   irp
        //

        nextStack   =   IoGetNextIrpStackLocation(Irp);
        nextStack-> MajorFunction   =   IRP_MJ_INTERNAL_DEVICE_CONTROL;
        nextStack-> Parameters.Others.Argument1   =   (PVOID)   urb;
        nextStack-> Parameters.DeviceIoControl.IoControlCode   =   
                                                                                          IOCTL_INTERNAL_USB_SUBMIT_URB;

        IoSetCompletionRoutine(Irp,   
                                                      (PIO_COMPLETION_ROUTINE)Ezusb_ReadWriteCompletion,
                                                      rwContext,
                                                      TRUE,
                                                      TRUE,
                                                      TRUE);

        //
        //   since   we   return   STATUS_PENDING   call   IoMarkIrpPending.
        //   This   is   the   boiler   plate   code.
        //   This   may   cause   extra   overhead   of   an   APC   for   the   Irp   completion
        //   but   this   is   the   correct   thing   to   do.
        //

        IoMarkIrpPending(Irp);

        //BulkUsb_IoIncrement(deviceExtension);

        ntStatus   =   IoCallDriver(deviceExtension-> StackDeviceObject,
                                                        Irp);

        if(!NT_SUCCESS(ntStatus))   {


                //
                //   if   the   device   was   yanked   out,   then   the   pipeInformation   
                //   field   is   invalid.
                //   similarly   if   the   request   was   cancelled,   then   we   need   not
                //   invoked   reset   pipe/device.
                //
                if((ntStatus   !=   STATUS_CANCELLED)   &&   
                      (ntStatus   !=   STATUS_DEVICE_NOT_CONNECTED))   {
                        ULONG   pipenum   =   *((PULONG)   irpStack);
                        /*ntStatus   =   UsbResetPipe(DeviceObject,
                                                                          pipeInformation);*/
                        ntStatus   =   UsbResetPipe(DeviceObject,
                                                                          pipenum);
        
                        if(!NT_SUCCESS(ntStatus))   {


                                //ntStatus   =   BulkUsb_ResetDevice(DeviceObject);
                        }
                }
                else   {

                }
        }

        //
        //   we   return   STATUS_PENDING   and   not   the   status   returned   by   the   lower   layer.
        //
        return   STATUS_PENDING;

BulkUsb_DispatchRead_Exit:

        Irp-> IoStatus.Status   =   ntStatus;
        Irp-> IoStatus.Information   =   0;

        IoCompleteRequest(Irp,   IO_NO_INCREMENT);


        return   ntStatus;
}

使用特权

评论回复
板凳
zhuww|  楼主 | 2010-8-18 22:42 | 只看该作者
这是我找资料写的一个写例程.我用softIce进行调试时if(fileObject   &&   fileObject-> FsContext)   这里就没有往下执行,直接跳到
        else   {

                ntStatus   =   STATUS_INVALID_HANDLE;
                goto   BulkUsb_DispatchRead_Exit;
        }
了,不知道为什么,我也只是从别的地方抄来的,肯定不对,请高手指正.

使用特权

评论回复
地板
llia| | 2010-8-18 22:48 | 只看该作者
FsContext这个具体内容不太清楚,最有可能这个东西没有搞好。

使用特权

评论回复
5
lium| | 2010-8-18 22:59 | 只看该作者
先确认68013A的firmware好了没有?

使用特权

评论回复
6
lium| | 2010-8-18 22:59 | 只看该作者
cypress没有提供driver sample code么?好像《usb原理与工程开发》有提供实例。

使用特权

评论回复
7
zhuww|  楼主 | 2010-8-18 23:16 | 只看该作者
这个是没有提供实例的,没实现IRP_MJ_READ的例程的,他们都是使用IRP_MJ_DEVICE_CONTROL这个例程来传输数据的

使用特权

评论回复
8
lium| | 2010-8-18 23:17 | 只看该作者
那最终是firmware的问题,还是driver的问题?
如果是driver的问题,if(fileObject && fileObject- >FsContext) 判断为false的原因是什么?
想知道下...

使用特权

评论回复
9
zhuww|  楼主 | 2010-8-18 23:18 | 只看该作者
if(fileObject && fileObject- >FsContext)

这个文件对象是需要创建的,在驱动加载时,这个不好控制, 我没有采用此方法,这种方法是DDK的例子的方法.

使用特权

评论回复
10
fhy2005| | 2010-8-31 11:00 | 只看该作者
usb串口控制程序,谁有?

使用特权

评论回复
11
fhy2005| | 2010-8-31 11:08 | 只看该作者
usb串口控制程序,谁有?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

893

主题

8252

帖子

1

粉丝