plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
20楼#
发布于:2002-03-28 21:36
USB等时传输

例程如下:

NTSTATUS Iso_ReadWrite(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN BOOLEAN Read)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PUSBD_PIPE_INFORMATION pipeHandle;
    PFILE_OBJECT fileObject;
    PIO_STACK_LOCATION irpStack, nextStack;
    PDEVICE_EXTENSION deviceExtension;
    PURB urb;
    PUSB_RW_CONTEXT context = NULL;

    if (!Irp->MdlAddress) { // this is NULL  for a 0-len request; just return SUCCESS
       goto IsoUsb_Read_Reject;
    }

    Pub_IncrementIoCount(DeviceObject);

    deviceExtension = DeviceObject->DeviceExtension;
//===========================================
    if (!Pub_CanAcceptIoRequests(DeviceObject)) {
        ntStatus = STATUS_DELETE_PENDING;
        Irp->IoStatus.Status = ntStatus;
        //===========================================
        Pub_DecrementIoCount(DeviceObject);
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return ntStatus;
    }

    irpStack = IoGetCurrentIrpStackLocation (Irp);

    fileObject = irpStack->FileObject;

    pipeHandle =  fileObject->FsContext;

    if (!pipeHandle) {
       ntStatus = STATUS_INVALID_HANDLE;
       goto IsoUsb_Read_Reject;
    }

    // submit the write request to USB
//=============================================================
    Usb_ResetPipe(DeviceObject, pipeHandle, FALSE);
    //============================================================
    urb = Usb_BuildIsoRequest(DeviceObject,
                                 Irp,
                                 pipeHandle,
                                 TRUE);
    if (urb) {

        nextStack = IoGetNextIrpStackLocation(Irp);
        ASSERT(nextStack != NULL);
        ASSERT(DeviceObject->StackSize>1);

        nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
        nextStack->Parameters.Others.Argument1 = urb;
        nextStack->Parameters.DeviceIoControl.IoControlCode =
            IOCTL_INTERNAL_USB_SUBMIT_URB;
//=======================================================
        IoSetCompletionRoutine(Irp,
                               Usb_IsoReadWrite_Complete,
                               urb,   // pass URB as context
                               TRUE,  // invoke on success
                               TRUE,  // invoke on error
                               TRUE); // invoke on cancel

        ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
                                Irp);
        goto IsoUsb_Read_Done;
    } else {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

IsoUsb_Read_Reject:

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

    IoCompleteRequest (Irp,
                       IO_NO_INCREMENT);
IsoUsb_Read_Done:
    return ntStatus;
}

NTSTATUS Usb_ResetPipe(
    IN PDEVICE_OBJECT DeviceObject,
    IN PUSBD_PIPE_INFORMATION Pipe,
    IN BOOLEAN IsoClearStall
)
{
    NTSTATUS ntStatus;
    PURB urb;

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

    if (urb) {

        urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
        urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
        urb->UrbPipeRequest.PipeHandle = Pipe->PipeHandle;
//==============================================================
        ntStatus = Usb_CallUSBD(DeviceObject, urb);
        ExFreePool(urb);
    } else {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    if (NT_SUCCESS(ntStatus) && IsoClearStall &&
        (Pipe->PipeType == UsbdPipeTypeIsochronous)) {
        
        urb = ExAllocatePool(NonPagedPool,
                             sizeof(struct _URB_CONTROL_FEATURE_REQUEST));

        if (urb) {
            UsbBuildFeatureRequest(urb,
                                   URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,
                                   USB_FEATURE_ENDPOINT_STALL,
                                   Pipe->EndpointAddress,
                                   NULL);
//===============================================================
            ntStatus = Usb_CallUSBD(DeviceObject, urb);

            ExFreePool(urb);
        } else {
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        }
    }
    return ntStatus;
}

PURB Usb_BuildIsoRequest(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PUSBD_PIPE_INFORMATION PipeHandle,
    IN BOOLEAN Read)
{
    ULONG siz;
    ULONG length, packetSize, numPackets, i;
    PURB urb = NULL;
    PIO_STACK_LOCATION irpSp;
    LARGE_INTEGER byteOffset;

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    length = MmGetMdlByteCount(Irp->MdlAddress);

    byteOffset = irpSp->Parameters.Read.ByteOffset;

    packetSize = PipeHandle->MaximumPacketSize;
    numPackets = length/packetSize;
    if (numPackets*packetSize < length) {
        numPackets++;
    }
    
    siz = GET_ISO_URB_SIZE(numPackets);
    urb = ExAllocatePool(NonPagedPool, siz);

    if (urb) {
        RtlZeroMemory(urb, siz);

        urb->UrbIsochronousTransfer.Hdr.Length = (USHORT) siz;
        urb->UrbIsochronousTransfer.Hdr.Function =
                    URB_FUNCTION_ISOCH_TRANSFER;
        urb->UrbIsochronousTransfer.PipeHandle =
                   PipeHandle->PipeHandle;
        urb->UrbIsochronousTransfer.TransferFlags =
            Read ? USBD_TRANSFER_DIRECTION_IN : 0;

        urb->UrbIsochronousTransfer.TransferBufferMDL =
            Irp->MdlAddress;
        urb->UrbIsochronousTransfer.TransferBufferLength =
            length;

        if (byteOffset.HighPart)
        {//========================================
            urb->UrbIsochronousTransfer.StartFrame =
                Usb_GetCurrentFrame(DeviceObject, Irp) +
                byteOffset.LowPart;
        }
        else
        {
            // start sending/receiving right away
            urb->UrbIsochronousTransfer.TransferFlags |=
                USBD_START_ISO_TRANSFER_ASAP;
        }

        urb->UrbIsochronousTransfer.NumberOfPackets = numPackets;
        urb->UrbIsochronousTransfer.UrbLink = NULL;

        for (i=0; i< urb->UrbIsochronousTransfer.NumberOfPackets; i++) {
            urb->UrbIsochronousTransfer.IsoPacket[ i ].Offset
                        = i * packetSize;
        }
    }
    return urb;
}

ULONG Usb_GetCurrentFrame (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp)
{
    PDEVICE_EXTENSION           deviceExtension;
    PIO_STACK_LOCATION          nextStack;
    NTSTATUS                    ntStatus;
    struct _URB_GET_CURRENT_FRAME_NUMBER urb;

    deviceExtension   = DeviceObject->DeviceExtension;

    // Initialize the URB
    //
    urb.Hdr.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;
    urb.Hdr.Length   = sizeof(urb);
    urb.FrameNumber = (ULONG)-1;

    // Set the IRP parameters to pass the URB down the stack
    //
    nextStack = IoGetNextIrpStackLocation(Irp);

    nextStack->Parameters.Others.Argument1 = &urb;

    nextStack->Parameters.DeviceIoControl.IoControlCode =
        IOCTL_INTERNAL_USB_SUBMIT_URB;                    

    nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;

    // Since this Irp is borrowed for URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
    // before it is passed down later for the real URB request after this
    // routine returns, set a completion routine which stop further completion
    // of the Irp.
    //
    IoSetCompletionRoutine(
        Irp,
        Usb_IsoCompletionStop, // this routine does nothing but return STATUS_MORE_PROCESSING_REQUIRED
        NULL,   // Context
        TRUE,   // InvokeOnSuccess
        TRUE,   // InvokeOnError
        TRUE);  // InvokeOnCancel


    // Now pass the Irp down the stack
    //
    ntStatus = IoCallDriver(
                   deviceExtension->TopOfStackDeviceObject,
                   Irp);

    // Don\'t need to wait for completion because
    // URB_FUNCTION_GET_CURRENT_FRAME_NUMBER will never return STATUS_PENDING

   return urb.FrameNumber;
}

NTSTATUS Usb_IsoCompletionStop (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context)

{
    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS Usb_IsoReadWrite_Complete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
)
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PURB                urb = Context;
    PUSBD_PIPE_INFORMATION pipeHandle;
    PFILE_OBJECT        fileObject;
    PIO_STACK_LOCATION    irpStack;
    ULONG               i;

    if (Irp->PendingReturned) {
        IoMarkIrpPending(Irp);
    }
    // ISSUE: check here for interesting iso error conditions
    for (i=0; i< urb->UrbIsochronousTransfer.NumberOfPackets; i++)
    {
        if (!USBD_SUCCESS(
            urb->UrbIsochronousTransfer.IsoPacket[ i ].Status)) {
            ntStatus =  STATUS_UNSUCCESSFUL; // set  error return code          
        }                
    }
    Irp->IoStatus.Information =
        urb->UrbBulkOrInterruptTransfer.TransferBufferLength;

    irpStack = IoGetCurrentIrpStackLocation (Irp);
    fileObject = irpStack->FileObject;
    // get pipe handle
    pipeHandle = fileObject->FsContext;
    Pub_DecrementIoCount(DeviceObject);                      
    ExFreePool(urb);
    return ntStatus;
}

[编辑 -  3/29/02 作者: plasma]
plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
21楼#
发布于:2002-03-28 21:44
USB等时传输流控制

例程如下:

NTSTATUS Usb_StartIsoStream(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    ULONG i;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpStack;
    ULONG inputBufferLength;
    ULONG outputBufferLength;
    PULONG_PTR streamObjectHandle;
    PISOUSB_STREAM_OBJECT streamObject;
    LARGE_INTEGER dueTime;
    BOOLEAN inQueue;
    PUSBD_PIPE_INFORMATION PipeInfo;
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

    irpStack = IoGetCurrentIrpStackLocation (Irp);
    streamObjectHandle = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    if (outputBufferLength  < sizeof(*streamObjectHandle)) {

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

        return STATUS_INVALID_PARAMETER;
    }

    streamObject = ExAllocatePool(NonPagedPool, sizeof(ISOUSB_STREAM_OBJECT));

    if (streamObject) {


        RtlZeroMemory(streamObject, sizeof(ISOUSB_STREAM_OBJECT));

        // hard code to 5th pipe; this is the iso in pipe on our test board
        PipeInfo = &(deviceExtension->UsbInterface->Pipes[4]);

        deviceExtension->PipeInfo[4].fPipeOpened = TRUE; // set flag for this pipe opened
        deviceExtension->OpenPipeCount++;

        // try to power up device if its not already in D0
        Usb_SelfSuspendOrActivate(DeviceObject, FALSE);

        streamObject->DeviceObject = DeviceObject;
        streamObject->PipeInfo = PipeInfo;
        streamObject->IsoStreamStarted = TRUE;

        // event to be set when PendingIrps == 0; signals stream can be stopped
        KeInitializeEvent(&streamObject->NoPendingIrpEvent, NotificationEvent, FALSE);

        // This initializes the pair of IRP/URBS that we will keep endlessly recycling
        // until the Iso stream is stoppped; at least one of these pairs will always be in
        // use and one will be available so continuous throughput is maintained.
        for (i=0; i< ISOUSB_MAX_IRP; i++) {
//===============================================================
            ntStatus = Usb_StartTransfer(DeviceObject,
                                        streamObject,
                                        i);

            if (!NT_SUCCESS(ntStatus)) {
                ;
                break;
            }

        }

        // We are returning the pointer to our stream object as an untyped handle to the user
        *streamObjectHandle = (ULONG_PTR) streamObject;
        // start the timeout DPC
        KeInitializeTimer(&streamObject->TimeoutTimer);
        //====================================================
        KeInitializeDpc(&streamObject->TimeoutDpc,
                        Usb_StreamTimeoutDPC,
                        streamObject);

        dueTime.QuadPart = -10000 * ISOUSB_STREAM_TIMEOUT_INTERVAL;

        inQueue = KeSetTimer(&streamObject->TimeoutTimer,
                             dueTime,
                             &streamObject->TimeoutDpc);


    } else {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }
    // We are returning the size of our stream object pointer to the user
    Irp->IoStatus.Information = sizeof(*streamObjectHandle);
    Irp->IoStatus.Status = ntStatus;
    return ntStatus;
}

NTSTATUS Usb_StartTransfer(
    IN PDEVICE_OBJECT DeviceObject,
    IN PISOUSB_STREAM_OBJECT StreamObject,
    IN ULONG Index)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    CCHAR stackSize;
    PDEVICE_EXTENSION deviceExtension;
    PISOUSB_TRANSFER_OBJECT transferObject;
    ULONG packetSize, numPackets, maxXferSize;

    maxXferSize = StreamObject->PipeInfo->MaximumTransferSize;  // We set this
    packetSize = StreamObject->PipeInfo->MaximumPacketSize;        // USBD sets this
    numPackets = maxXferSize / packetSize;

    deviceExtension = DeviceObject->DeviceExtension;
    transferObject = ExAllocatePool(NonPagedPool, sizeof(ISOUSB_TRANSFER_OBJECT));
    if (transferObject) {
        PIRP irp;

        RtlZeroMemory(transferObject,sizeof(ISOUSB_TRANSFER_OBJECT));

        StreamObject->TransferObjectList[Index] =
            transferObject;

        transferObject->StreamObject = StreamObject;

        stackSize = (CCHAR)(deviceExtension->TopOfStackDeviceObject->StackSize + 1);

        transferObject->Irp =
            irp = IoAllocateIrp(stackSize,
                                FALSE);

        transferObject->DataBuffer = ExAllocatePool(NonPagedPool,
                                                    numPackets *
                                                    StreamObject->PipeInfo->MaximumPacketSize);

        transferObject->Urb =
            ExAllocatePool(NonPagedPool, GET_ISO_URB_SIZE(numPackets));

        if (transferObject->Urb && transferObject->DataBuffer) {

            PIO_STACK_LOCATION nextStack;
            NTSTATUS status;
//=============================================================
            Usb_InitializeStreamUrb(DeviceObject, transferObject);

            nextStack = IoGetNextIrpStackLocation(irp);
            ASSERT(nextStack != NULL);

            nextStack->Parameters.Others.Argument1 = transferObject->Urb;
            nextStack->Parameters.DeviceIoControl.IoControlCode =
                IOCTL_INTERNAL_USB_SUBMIT_URB;
            nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
//=========================================================
            IoSetCompletionRoutine(irp,
                    Usb_IsoIrp_Complete,
                    transferObject, //pass transfer object as Context
                    TRUE,  // Invoke on Success
                    TRUE,  // Invoke on Error
                    TRUE); // Invoke on Cancel

            //
            // submit the request
            //

            StreamObject->PendingIrps++;           // increment this stream\'s pending irp count
            Pub_IncrementIoCount(DeviceObject); // also increment global pending IRP count

            status = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
                                  irp);

        } else {
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;

            if (transferObject->DataBuffer) {
                ExFreePool(transferObject->DataBuffer);
            }

            if (transferObject->Urb) {
                ExFreePool(transferObject->Urb);
            }

        }

    } else {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }
    return ntStatus;
}

NTSTATUS Usb_IsoIrp_Complete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context)
{
    NTSTATUS status;
    PDEVICE_EXTENSION deviceExtension;
    PDEVICE_OBJECT deviceObject;
    PISOUSB_TRANSFER_OBJECT transferObject;
    PISOUSB_STREAM_OBJECT streamObject;
    PIO_STACK_LOCATION nextStack;


    transferObject = Context;
    streamObject = transferObject->StreamObject;
    deviceObject = streamObject->DeviceObject;
    deviceExtension = deviceObject->DeviceExtension;

    streamObject->PendingIrps--;           // Decrement this stream\'s pending irp count
    if (!streamObject->PendingIrps) {    // back to 0? signal no pending irps event
        KeSetEvent(&streamObject->NoPendingIrpEvent,
                   1,
                   FALSE);
     }

    Pub_DecrementIoCount(deviceObject); // also deccrement global pending IRP count

    // Check the IRP and URB status in the transferObject
    // Here is where a driver for a real device would collect and/or process data in the buffers
//==========================================================
    status = Usb_ProcessTransfer(transferObject);
    if(!NT_SUCCESS(status)) {
        Usb_ResetParentPort(DeviceObject);
    }

    // See if a stop stream has been requested..
    if(streamObject->IsoStreamStarted) {// this is set FALSE when we get a stop stream ioctl request

        // Last xfer was OK and no stop has been requested;
        // Resubmit the whole thing again and recycle it..
        //=======================================================
        Usb_InitializeStreamUrb(DeviceObject, transferObject);

        nextStack = IoGetNextIrpStackLocation(Irp);
        ASSERT(nextStack != NULL);

        nextStack->Parameters.Others.Argument1 = transferObject->Urb;
        nextStack->Parameters.DeviceIoControl.IoControlCode =
            IOCTL_INTERNAL_USB_SUBMIT_URB;
        nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;


        IoSetCompletionRoutine(Irp,
                Usb_IsoIrp_Complete,
                transferObject, //pass transfer object as Context
                TRUE,  // Invoke on Success
                TRUE,  // Invoke on Error
                TRUE); // Invoke on Cancel


        // increment this stream object\'s pending irp count
        streamObject->PendingIrps++;
        // increment this stream object\'s total times recycled count
        streamObject->TimesRecycled++;
        // also increment global pending IRP count
        Pub_IncrementIoCount(deviceObject);

        //
        // Resubmit the request...
        // Note that if the driver has actually done a  fair amount of data processing
        // or copying from packet buffers, you may want to schedule a dpc
        // to resubmit instead of doing it here
        //
        status = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
                              Irp);
    }
    return STATUS_MORE_PROCESSING_REQUIRED;
}

//=================================================
NTSTATUS Usb_ProcessTransfer(IN PISOUSB_TRANSFER_OBJECT TransferObject)
{
    NTSTATUS ntStatus;
    USBD_STATUS usbdStatus;
    PIRP irp;
    PURB urb;
    PISOUSB_STREAM_OBJECT StreamObject;
    ULONG i;

    irp = TransferObject->Irp;
    StreamObject = TransferObject->StreamObject;
    urb = TransferObject->Urb;
    ntStatus = irp->IoStatus.Status;

    if (!NT_SUCCESS(ntStatus)) {
        ;
    }
    else {
    }
    // now check the urb header
    usbdStatus = urb->UrbHeader.Status;

    if (!USBD_SUCCESS(usbdStatus)) {
        ;
    }
    else {
    }
    // check the Urb packets
    for (i=0; i< urb->UrbIsochronousTransfer.NumberOfPackets; i++)
    {

        StreamObject->TotalPacketsProcessed++;

        if (!USBD_SUCCESS(urb->UrbIsochronousTransfer.IsoPacket[ i ].Status)) {

            ntStatus =  STATUS_UNSUCCESSFUL; // set  error return code

            StreamObject->ErrorPacketCount++;
        }
        else {
            // Successfull;
            // Note that here is the place we would  do any data processing/copying to frame
            // buffers, for example , if we were a video capture device, etc ...
            StreamObject->TotalBytesProcessed += urb->UrbIsochronousTransfer.IsoPacket[ i ].Length;
        }
    }
    return ntStatus;
}

NTSTATUS Usb_StopIsoStream(
    IN PDEVICE_OBJECT DeviceObject,
    IN PISOUSB_STREAM_OBJECT StreamObject,
    IN PIRP Irp
)
{
    PUSBD_PIPE_INFORMATION pipe;
    int i;
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
    ULONG packetSize, numPackets, maxXferSize;


    // validate the input parm; its DeviceObject member should match our DeviceObject

    // See if we were called with a bogus or NULL StreamObject parm;
    // This could happen if user calls without ever having successfully started a stream
    if (!StreamObject || (StreamObject->DeviceObject != DeviceObject))
        return STATUS_INVALID_PARAMETER;

    maxXferSize = StreamObject->PipeInfo->MaximumTransferSize;  // We set this
    packetSize = StreamObject->PipeInfo->MaximumPacketSize;        // USBD sets this
    numPackets = maxXferSize / packetSize;

    // Tell Usb_StreamTimeoutDPC() not to reschedule itself on next timeout
    // This also flags Usb_IsoIrp_Complete() to stop recycling the pair of stream IRP/Urbs
    StreamObject->IsoStreamStarted = FALSE;

    // Wait for any io request pending for this stream object to
    // complete before returning success.
    // This  event is set when streamObject->PendingIrpCount goes to 0
    KeWaitForSingleObject(
                &StreamObject->NoPendingIrpEvent,
                Suspended,
                KernelMode,
                FALSE,
                NULL);
    // Free all the buffers, URBS, and Irps associated with our stream object
    for (i=0; i< ISOUSB_MAX_IRP; i++) {
        PISOUSB_TRANSFER_OBJECT transferObject;

        transferObject = StreamObject->TransferObjectList[ i ];

        IoFreeIrp(transferObject->Irp);

        ExFreePool(transferObject->Urb);

        ExFreePool(transferObject->DataBuffer);

        ExFreePool(transferObject);
    }

    ExFreePool(StreamObject); // also free the stream object itself


    // Close our Iso input pipe;
    // Hard-code to 5th pipe; this is the iso input pipe on our test board
    pipe = &(deviceExtension->UsbInterface->Pipes[4]);

    deviceExtension->PipeInfo[4].fPipeOpened = FALSE; // set flag for this pipe closed
    deviceExtension->OpenPipeCount--;

    // ISSUE? Not sure why this is neccesary, but it is...
    Usb_ResetParentPort(DeviceObject);

    // try to power down device if we just closed the last open pipe
    Usb_SelfSuspendOrActivate(DeviceObject, TRUE);

    return STATUS_SUCCESS;

}
NTSTATUS Usb_InitializeStreamUrb(
    IN PDEVICE_OBJECT DeviceObject,
    IN PISOUSB_TRANSFER_OBJECT TransferObject)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    ULONG siz;
    ULONG packetSize, numPackets, maxXferSize, i;
    PURB urb;
    PISOUSB_STREAM_OBJECT streamObject = TransferObject->StreamObject;

    urb = TransferObject->Urb;

    maxXferSize = streamObject->PipeInfo->MaximumTransferSize;  // We set this
    packetSize = streamObject->PipeInfo->MaximumPacketSize;        // USBD sets this
    numPackets = maxXferSize / packetSize;

    siz = GET_ISO_URB_SIZE(numPackets);

    RtlZeroMemory(urb, siz);

    urb->UrbIsochronousTransfer.Hdr.Length = (USHORT) siz;
    urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
    urb->UrbIsochronousTransfer.PipeHandle = streamObject->PipeInfo->PipeHandle;

    // We are reading from the device
    urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN;

    // A device will always use either TransferBufferMDL or TransferBuffer, NEVER both
    urb->UrbIsochronousTransfer.TransferBufferMDL = NULL;
    urb->UrbIsochronousTransfer.TransferBuffer = TransferObject->DataBuffer;

    urb->UrbIsochronousTransfer.TransferBufferLength =
        numPackets * packetSize;

    // start sending/receiving right away
    urb->UrbIsochronousTransfer.TransferFlags |=
            USBD_START_ISO_TRANSFER_ASAP;

    urb->UrbIsochronousTransfer.NumberOfPackets = numPackets;
    urb->UrbIsochronousTransfer.UrbLink = 0;

    for (i=0; i< urb->UrbIsochronousTransfer.NumberOfPackets; i++) {
        urb->UrbIsochronousTransfer.IsoPacket[ i ].Offset
                    = i * packetSize;
    }
    return ntStatus;
}


VOID Usb_StreamTimeoutDPC(
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2)
{
    PDEVICE_EXTENSION deviceExtension;
    PDEVICE_OBJECT deviceObject;
    PISOUSB_STREAM_OBJECT streamObject;
    BOOLEAN inQueue;
    LARGE_INTEGER dueTime;

    streamObject = DeferredContext;
    deviceObject = streamObject->DeviceObject;
    deviceExtension = deviceObject->DeviceExtension;

    // schedule next one
    if (streamObject->IsoStreamStarted) {

        KeInitializeTimer(&streamObject->TimeoutTimer);
        KeInitializeDpc(&streamObject->TimeoutDpc,
                        Usb_StreamTimeoutDPC,
                        streamObject);

        dueTime.QuadPart = -10000 * ISOUSB_STREAM_TIMEOUT_INTERVAL;

        inQueue = KeSetTimer(&streamObject->TimeoutTimer,
                             dueTime,
                             &streamObject->TimeoutDpc);

        ASSERT(inQueue == FALSE);  // assert timer not already in system queue

    }
}


[编辑 -  3/29/02 作者: plasma]
plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
22楼#
发布于:2002-03-28 21:57
自定义头文件:

#define BULKUSB_TEST_BOARD_TRANSFER_BUFFER_SIZE (64 *1024)

#define USB_MAX_TRANSFER_SIZE 256    

// used to track driver-generated io irps for  read/write processing
typedef struct _USB_RW_CONTEXT {
    PURB Urb;
    PDEVICE_OBJECT DeviceObject;
    PIRP  Irp;
    PMDL  Mdl;
} USB_RW_CONTEXT, *PUSB_RW_CONTEXT;

// used to track information on pipes in use;
//  currently just to flag if opened or closed
typedef struct USB_PIPEINFO {

    BOOLEAN fPipeOpened;

} USB_PIPEINFO, *PUSB_PIPEINFO;

#define ISOUSB_MAX_IRP  2        // number of transfer objects to keep recycling

#define ISOUSB_STREAM_TIMEOUT_INTERVAL  100 // MS

typedef struct _ISOUSB_TRANSFER_OBJECT {
    struct _ISOUSB_STREAM_OBJECT *StreamObject;
    PIRP Irp;
    PURB Urb;
    PUCHAR DataBuffer;
} ISOUSB_TRANSFER_OBJECT, *PISOUSB_TRANSFER_OBJECT;

typedef struct _ISOUSB_STREAM_OBJECT {
    PDEVICE_OBJECT DeviceObject;
    ULONG PendingIrps;
    PISOUSB_TRANSFER_OBJECT TransferObjectList[ISOUSB_MAX_IRP];
    PUSBD_PIPE_INFORMATION PipeInfo;
    KDPC TimeoutDpc;
    KTIMER  TimeoutTimer;
    KEVENT NoPendingIrpEvent;
    BOOLEAN IsoStreamStarted;
    ULONG TimesRecycled;
    ULONG TotalPacketsProcessed;
    ULONG TotalBytesProcessed;
    ULONG ErrorPacketCount;
} ISOUSB_STREAM_OBJECT, *PISOUSB_STREAM_OBJECT;

//
// A structure representing the instance information associated with
// this particular device.
//

typedef struct _DEVICE_EXTENSION {
    // 提交Urbs的设备目标
    PDEVICE_OBJECT TopOfStackDeviceObject;

    // The bus driver object
    PDEVICE_OBJECT PhysicalDeviceObject;

    DEVICE_POWER_STATE CurrentDevicePowerState;
    //USB configuration information 句柄
    USBD_CONFIGURATION_HANDLE UsbConfigurationHandle;

    //以下是带自定义部分
    PUSB_CONFIGURATION_DESCRIPTOR UsbConfigurationDescriptor;


    // ptr to the USB device descriptor
    // for this device
    PUSB_DEVICE_DESCRIPTOR UsbDeviceDescriptor;

    // we support one interface
    // this is a copy of the info structure
    // returned from select_configuration or
    // select_interface
    PUSBD_INTERFACE_INFORMATION UsbInterface;

    //Bus drivers set the appropriate values in this structure in response
    //to an IRP_MN_QUERY_CAPABILITIES IRP. Function and filter drivers might
    //alter the capabilities set by the bus driver.
    DEVICE_CAPABILITIES DeviceCapabilities;

    // used to save the currently-being-handled system-requested power irp request
    PIRP PowerIrp;

    // used to save base Irp (user-originated via IOCTL) of staged read/write request
    PIRP BaseIrp;

    // used to save  URB of short, non-staged read/write requests
    PURB BaseUrb;

    // count of self-staged irps pending
    ULONG StagedPendingIrpCount;

    // count of self-staged bytes read or written so far
    ULONG StagedBytesTransferred;

    // set when PendingIoCount goes to 0; flags device can be removed
    KEVENT RemoveEvent;


    // set when Bulk_AsyncReadWrite_Complete() finishes or cancels last staged io irp
    KEVENT StagingDoneEvent;

    // set when PendingIoCount goes to 1 (1st increment was on add device)
    // this indicates no IO requests outstanding, either user, system, or otherwise
    KEVENT NoPendingIoEvent;

    // set to signal driver-generated power request is finished
    KEVENT SelfRequestedPowerIrpEvent;

    // spinlock used to protect inc/dec iocount logic
    KSPIN_LOCK    IoCountSpinLock;

    // incremented when device is added and any IO request is received;
    // decremented when any io request is completed or passed on, and when device is removed
    ULONG PendingIoCount;

    // count of open pipes
    ULONG OpenPipeCount;

    // ptr to array of structs to track pipeinfo;
    //  in this basic sample it\'s only used to track if open/closed;
    PUSB_PIPEINFO PipeInfo;

    // save ptr to array of info on self-generated IRPS for staged read/writes;
    //  will allocate this separately
    PUSB_RW_CONTEXT PendingIoIrps;

    // Name buffer for our named Functional device object link
    // The name is generated based on the driver\'s class GUID
    UNICODE_STRING DeviceLinkNameBuffer;

    //flag set when processing IRP_MN_REMOVE_DEVICE
    BOOLEAN DeviceRemoved;

     // flag set when driver has answered success to IRP_MN_QUERY_REMOVE_DEVICE
    BOOLEAN RemoveDeviceRequested;

    // flag set when driver has answered success to IRP_MN_QUERY_STOP_DEVICE
    BOOLEAN StopDeviceRequested;

    // flag set when device has been successfully started
    BOOLEAN DeviceStarted;

    // flag set when IRP_MN_WAIT_WAKE is received and we\'re in a power state
    // where we can signal a wait
    BOOLEAN EnabledForWakeup;

    // used to flag that we\'re currently handling a self-generated power request
    BOOLEAN SelfPowerIrp;

    // default power state to power down to on self-suspend
    ULONG PowerDownLevel;

    // default maximum transfer per io        
    ULONG MaximumTransferSize;  

    // spinlock used to protect test of deviceExtension->BaseIrp in
    // Bulk_StagedReadWrite()
    KSPIN_LOCK FastCompleteSpinlock;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

// function prototypes 功能函数原型
NTSTATUS PnP(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS Usb_StartIsoStream(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS Usb_StopIsoStream(
            IN PDEVICE_OBJECT DeviceObject,
            IN PISOUSB_STREAM_OBJECT StreamObject,
            IN PIRP Irp);

NTSTATUS Usb_IsoIrp_Complete(
            IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,
            IN PVOID Context);

NTSTATUS sys_Control(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

VOID     Unload(IN PDRIVER_OBJECT DriverObject);

NTSTATUS Usb_StartDevice(IN  PDEVICE_OBJECT DeviceObject);

NTSTATUS Usb_StopDevice(IN  PDEVICE_OBJECT DeviceObject);

NTSTATUS PnP_RemoveDevice(IN  PDEVICE_OBJECT DeviceObject);

NTSTATUS Usb_CallUSBD(IN PDEVICE_OBJECT DeviceObject,IN PURB Urb);

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject,
                   IN PDEVICE_OBJECT PhysicalDeviceObject);

NTSTATUS Usb_ConfigureDevice(IN  PDEVICE_OBJECT DeviceObject);

NTSTATUS Pub_IrpCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
                                IN PIRP Irp,IN PVOID Context);

NTSTATUS pwr_PoRequestCompletion(
            IN PDEVICE_OBJECT DeviceObject,
            IN UCHAR                MinorFunction,
            IN POWER_STATE          PowerState,
            IN PVOID                Context,
            IN PIO_STATUS_BLOCK     IoStatus);

NTSTATUS pwr_PoSelfRequestCompletion(
            IN PDEVICE_OBJECT  DeviceObject,
            IN UCHAR                MinorFunction,
            IN POWER_STATE          PowerState,
            IN PVOID                Context,
            IN PIO_STATUS_BLOCK     IoStatus);

PURB     Usb_BuildIsoRequest(
            IN PDEVICE_OBJECT DeviceObject,
            IN PIRP Irp,
            IN PUSBD_PIPE_INFORMATION PipeHandle,
            IN BOOLEAN Read);

NTSTATUS Usb_GetPortStatus(IN PDEVICE_OBJECT DeviceObject,
                           IN PULONG PortStatus);

NTSTATUS Usb_ResetParentPort(IN IN PDEVICE_OBJECT DeviceObject);

NTSTATUS pwr_SelfRequestPowerIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN POWER_STATE PowerState);

BOOLEAN pwr_SetDevicePowerState(
    IN PDEVICE_OBJECT DeviceObject,
    IN DEVICE_POWER_STATE DeviceState);

NTSTATUS Usb_IsoReadWrite_Complete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context);

NTSTATUS pwr_PowerIrp_Complete(
    IN PDEVICE_OBJECT NullDeviceObject,
    IN PIRP Irp,
    IN PVOID Context);

NTSTATUS AddDevice_QueryCapabilities(
    IN PDEVICE_OBJECT PdoDeviceObject,
    IN PDEVICE_CAPABILITIES DeviceCapabilities);

NTSTATUS Iso_ReadWrite(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN BOOLEAN Read);

NTSTATUS win32_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS win32_Write(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS win32_Create(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS Usb_AbortPipes(IN PDEVICE_OBJECT DeviceObject);

NTSTATUS win32_IOCTL(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS Usb_SelectInterface(
    IN PDEVICE_OBJECT DeviceObject,
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);

NTSTATUS Usb_ResetDevice(IN PDEVICE_OBJECT DeviceObject);

NTSTATUS win32_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS Usb_ResetPipe(IN PDEVICE_OBJECT DeviceObject,
                       IN PUSBD_PIPE_INFORMATION Pipe,
                       IN BOOLEAN IsoClearStall);

VOID Pub_IncrementIoCount(IN PDEVICE_OBJECT DeviceObject);

LONG Pub_DecrementIoCount(
    IN PDEVICE_OBJECT DeviceObject);  

NTSTATUS pwr(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp);    

NTSTATUS Usb_SelfSuspendOrActivate(
    IN PDEVICE_OBJECT DeviceObject,
    IN BOOLEAN fSuspend);

BOOLEAN Pub_CanAcceptIoRequests(
    IN PDEVICE_OBJECT DeviceObject);

ULONG Usb_GetCurrentFrame (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp);

NTSTATUS Usb_IsoCompletionStop (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context);

PUSB_PIPEINFO win32_PipeWithName(
    IN PDEVICE_OBJECT DeviceObject,
    IN PUNICODE_STRING FileName);

NTSTATUS Bulk_ReadWrite(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN BOOLEAN Read);

NTSTATUS Bulk_SingleUrbReadWrite(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN BOOLEAN Read);

PURB Bulk_BuildAsyncRequest(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PUSBD_PIPE_INFORMATION PipeHandle,
    IN BOOLEAN Read);

NTSTATUS Bulk_AsyncReadWrite_Complete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context);

NTSTATUS Bulk_SimpleReadWrite_Complete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context);

BOOLEAN Usb_CancelPendingIo(IN PDEVICE_OBJECT DeviceObject);

NTSTATUS Usb_StartTransfer(
    IN PDEVICE_OBJECT DeviceObject,
    IN PISOUSB_STREAM_OBJECT StreamObject,
    IN ULONG Index);

NTSTATUS Usb_ProcessTransfer(IN PISOUSB_TRANSFER_OBJECT TransferObject);

NTSTATUS Usb_InitializeStreamUrb(
    IN PDEVICE_OBJECT DeviceObject,
    IN PISOUSB_TRANSFER_OBJECT TransferObject);

VOID Usb_StreamTimeoutDPC(
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2);


[编辑 -  3/29/02 作者: plasma]
plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
23楼#
发布于:2002-03-28 22:10
自定义驱动程序与Windows应用程序交互控制码

#define ISOUSB_IOCTL_INDEX  0x8000

#define IOCTL_ISOUSB_GET_CONFIG_DESCRIPTOR     CTL_CODE(FILE_DEVICE_UNKNOWN,  \\
                                                   ISOUSB_IOCTL_INDEX,\\
                                                   METHOD_BUFFERED,  \\
                                                   FILE_ANY_ACCESS)
                                                  
#define IOCTL_ISOUSB_RESET_DEVICE   CTL_CODE(FILE_DEVICE_UNKNOWN,  \\
                                                   ISOUSB_IOCTL_INDEX+1,\\
                                                   METHOD_BUFFERED,  \\
                                                   FILE_ANY_ACCESS)
                                                  
#define IOCTL_ISOUSB_RESET_PIPE  CTL_CODE(FILE_DEVICE_UNKNOWN,  \\
                                                   ISOUSB_IOCTL_INDEX+2,\\
                                                   METHOD_BUFFERED,  \\
                                                   FILE_ANY_ACCESS)
                                                          
#define IOCTL_ISOUSB_STOP_ISO_STREAM     CTL_CODE(FILE_DEVICE_UNKNOWN,  \\
                                                   ISOUSB_IOCTL_INDEX+3,\\
                                                   METHOD_BUFFERED,  \\
                                                   FILE_ANY_ACCESS)

#define IOCTL_ISOUSB_START_ISO_STREAM     CTL_CODE(FILE_DEVICE_UNKNOWN,  \\
                                                   ISOUSB_IOCTL_INDEX+4,\\
                                                   METHOD_BUFFERED,  \\
                                                   FILE_ANY_ACCESS)


[编辑 -  3/29/02 作者: plasma]
plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
24楼#
发布于:2002-03-28 22:31
应该可以换页了吧!

以上是整理 DDK 中的 USB 驱动例程,下面把这个工程文件打包如下。工程开发环境是VC++6.0,调试WINDOWS 2000 DDK。
下在后请先修改 nmakedrv.bat

愿我的这部分工作能为您、为国人做出点贡献!

一些地方我不是很清楚,希望在大家共同探讨,多把经验帖出来,促进共同进步,促进国人共同提高!
plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
25楼#
发布于:2002-03-28 22:37
上一贴没有换页只好再来一次,这回附带的是自解压文件。

以上是整理 DDK 中的 USB 驱动例程,下面把这个工程文件打包如下。工程开发环境是VC++6.0,调试WINDOWS 2000 DDK。
下在后请先修改 nmakedrv.bat

愿我的这部分工作能为您、为国人做出点贡献!

一些地方我不是很清楚,希望在大家共同探讨,多把经验贴出来,促进共同进步,促进国人共同提高!

plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
26楼#
发布于:2002-03-29 10:16
接口信息结构:

typedef struct _USBD_PIPE_INFORMATION {
    // OUTPUT
    // 这一段由USBD填写
    USHORT MaximumPacketSize;  // 最大传输包大小
    UCHAR EndpointAddress;     // 8位端点地址(包含方向),有端点描述符获得
    UCHAR Interval;            // 中断管道轮寻时间(ms)
    USBD_PIPE_TYPE PipeType;   // 管道传输类型
    USBD_PIPE_HANDLE PipeHandle;
    // INPUT
    // 这一段由客户驱动填写
    ULONG MaximumTransferSize; // Maximum size for a single request
                               // in bytes.
    ULONG PipeFlags;           //
} USBD_PIPE_INFORMATION, *PUSBD_PIPE_INFORMATION;

// values for PipeFlags field in USBD_PIPE_INFORMATION field

#define USBD_PF_CHANGE_MAX_PACKET       0x00000001
#define USBD_PF_DOUBLE_BUFFER           0x00000002
#define USBD_PF_FAST_ISO                0x00000004
#define USBD_PF_VALID_MASK    (USBD_PF_CHANGE_MAX_PACKET | \\
                               USBD_PF_DOUBLE_BUFFER)

// USBD interface information structure
// this structure is returned for each interface opened thru an
// SELECT_CONFIGURATION or SELECT_INTERFACE request.

typedef struct _USBD_INTERFACE_INFORMATION {
    USHORT Length;       // 结构长度(包括管道信息结构长度)
    // INPUT
    // Interface number and Alternate setting this
    // structure is associated with
    UCHAR InterfaceNumber;
    UCHAR AlternateSetting;
    // OUTPUT
    // 这一段由USBD填写
    UCHAR Class;
    UCHAR SubClass;
    UCHAR Protocol;
    UCHAR Reserved;
    USBD_INTERFACE_HANDLE InterfaceHandle;
    ULONG NumberOfPipes;
    // INPUT/OUPUT
    // see PIPE_INFORMATION
#ifdef OSR21_COMPAT    
    USBD_PIPE_INFORMATION Pipes[0];
#else    
    USBD_PIPE_INFORMATION Pipes[1];
#endif    
} USBD_INTERFACE_INFORMATION, *PUSBD_INTERFACE_INFORMATION;
halley
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2002-10-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
27楼#
发布于:2002-04-11 10:00
Thanks very much
 :~)
luckyrex
驱动小牛
驱动小牛
  • 注册日期2002-04-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分185分
  • 威望20点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
28楼#
发布于:2002-04-11 15:22
例程中既有\"USB等时传输\"又有\"USB等时传输流控制 \",好象
各成一套体系,两者有什么区别和联系?
luronghua
驱动牛犊
驱动牛犊
  • 注册日期2002-04-08
  • 最后登录2002-07-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
29楼#
发布于:2002-04-11 18:13
楼上的大侠问的好, 二者有何区别和联系??能否详述?
dahello
驱动中牛
驱动中牛
  • 注册日期2001-06-16
  • 最后登录2004-06-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
30楼#
发布于:2002-04-12 14:51
老兄的耐性和毅力值得尊敬!谢谢!继续努力
不懂就问 :D
dahello
驱动中牛
驱动中牛
  • 注册日期2001-06-16
  • 最后登录2004-06-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
31楼#
发布于:2002-04-12 15:24
在工程目录中创建下列4个编译配置文件

文件:nmakedrv.bat

@echo off
if \"%1\"==\"\" goto exit
rem DDK安装路径
set mDDKDir=E:\\NTDDK

if not exist %mDDKDir%\\bin\\setenv.bat goto exit
call %mDDKDir%\\bin\\setenv %mDDKDir% %1

rem 转入工程目录
E:
cd \\temp1
build -b -w %2 %3 %4 %5 %6 %7 %8 %9
:exit

注:DDK安装路径、转入工程目录需自己修改

文件:Sources

TARGETNAME=temp1
TARGETTYPE=DRIVER
DRIVERTYPE=WDM
TARGETPATH=OBJ

INCLUDES=$(BASEDIR)\\inc;
TARGETLIBS=$(DDK_LIB_PATH)\\usbd.lib

USE_MAPSYM=1

SOURCES=  \\
    script1.rc \\
    IusbDbg.c \\
    IsoUsb.c  \\
    IsoPnP.c \\
    IsoPwr.c \\
    IoctlIso.c   \\
    IsoStrm.c \\
    OcrwIso.c

NTTARGETFILES=PostBuildSteps

注:temp1 为自定义工程文件名;TARGETLIBS指用到的库列表;SOURCES源文件(不

要头文件),资源文件列表。这三处需自己修改。

下面两个文件不用修改,按此建好即可。

文件:MAKEFILE

#
# DO NOT EDIT THIS FILE!!!  Edit .\\sources. if you want to add a new

source
# file to this component.  This file merely indirects to the real make

file
# that is shared by all the driver components of the Windows NT DDK
#

!INCLUDE $(NTMAKEENV)\\makefile.def

文件:Makefile.inc

PostBuildSteps: $(TARGET)
!if \"$(DDKBUILDENV)\"==\"free\"
rebase -B 0x10000 -X . $(TARGET)
!endif
copy $(TARGET) $(WINDIR)\\system32\\drivers

注:此 copy 是将你的驱动程序复制到系统system32\\drivers目录;利于重新启动设

备时启动新的驱动程序。



请教老兄一个问题,makefile.inc有什么用呢?
我开发驱动怎么没用到呢??
谢谢!
不懂就问 :D
yxy3115
驱动牛犊
驱动牛犊
  • 注册日期2002-03-12
  • 最后登录2004-03-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
32楼#
发布于:2002-04-12 16:29
我用的是CYPRESS公司的AN2131开发板,现在可以使用HEX2C将HEX文件生成C文件,是否可以直接用DDK生成SYS文件,而不需另外编写程序就能使用新的USB设备?另外请教如何设置和使用DDK?请各位高手赐教,非常感谢


 
dahello
驱动中牛
驱动中牛
  • 注册日期2001-06-16
  • 最后登录2004-06-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
33楼#
发布于:2002-04-12 16:41
makefile.inc有什么用呢?谢谢请指教
不懂就问 :D
plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
34楼#
发布于:2002-04-12 17:12
文件 Makefile.inc 是在当前工程目录下自己建立的,只要把

PostBuildSteps: $(TARGET)
!if \"$(DDKBUILDENV)\"==\"free\"
rebase -B 0x10000 -X . $(TARGET)
!endif
copy $(TARGET) $(WINDIR)\\system32\\drivers

存入即可。

它的作用我已经在注释中写了。

主要是在编译驱动文件时,会自动将编译好的驱动程序copy到系统目录system32\\drivers下,免去了手工copy。
完成这一过程的前提是停止以前编译的驱动程序,如果是类似于USB设备,只要拔下设备,驱动程序就会停止,完成上述copy,再插入设备,新的驱动程序就会启动。

dahello
驱动中牛
驱动中牛
  • 注册日期2001-06-16
  • 最后登录2004-06-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
35楼#
发布于:2002-04-13 08:37
哦,就是重新编译后,不必重新安装驱动了, 可以自动更新了!
谢谢!
不懂就问 :D
luckyrex
驱动小牛
驱动小牛
  • 注册日期2002-04-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分185分
  • 威望20点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
36楼#
发布于:2002-04-13 14:43
plasma, 能不能讲解一下你的例子中“USB等时传输”和
“USB等时传输流控制 ”有什么联系和区别,谢谢。
yxy3115
驱动牛犊
驱动牛犊
  • 注册日期2002-03-12
  • 最后登录2004-03-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
37楼#
发布于:2002-04-13 16:40
Plasma,能不能请教你几个问题,我现在使用的是CYPRESS公司的AN2131开发板,根据文档的说明,可以使用CYPRESS\\USB\\DRIVERS\\HEX2C下面的HEX2C将我自己的HEX文件转换成***.C文件,然后用该文件代替CYPRESS\\USB\\DRIVERS\\EZLOADER下的firmware.C,再用DDK编译生成***.SYS文件。我想请教你,如何使用DDK编译,是不是需要对安装完的DDK进行一些环境的配置,还是直接使用CHECKED或FREE进行编译,再修改一些相关的文件就可以让计算机能使用新的USB设备?在这个过程中是否需要C++?请各位高手不要笑我的问题而不吝赐教,在下非常感谢!!
bdoniel
驱动牛犊
驱动牛犊
  • 注册日期2002-04-21
  • 最后登录2002-04-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
38楼#
发布于:2002-04-22 17:01
plasma这样的人少,所以中国的程序员们进步极慢!!!!!!!!!!!!!!!!!!
kuaiyu
驱动牛犊
驱动牛犊
  • 注册日期2001-12-02
  • 最后登录2003-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
39楼#
发布于:2002-04-24 15:06
真的非常感谢你!你太好了!
刘庄(kuaiyu)
游客

返回顶部