Windows驱动_USB驱动之五

                    关于接下来的一些安排,关于DirectX3D的学习,书中的例子基本学习了一遍,后续,我还会找另外两本稍微深度点的书继续学习,然后进入开源游戏引擎的学习。目前,我会把重心重新放到驱动这边来,后续,会从USB驱动,文件过滤驱动,文件小过滤驱动进入,继续学习。

 

                   昨天,我们看到了USB的每帧传输的最大长度,在USB的规格里面将到,HighSpeed是480Mbit/s FullSpeed 12Mbit/S,定义1毫秒传输Frame的数据,125微秒传送一MicorFrame,所以我们很好理解下面的代码:

    //
    // For high-speed isochronous endpoints, the bInterval value is used
    // as the exponent for a 2^(bInterval-1) value expressed in
    // microframes; e.g., a bInterval of 4 means a period of 8 (2^(4-1))
    // microframes. The bInterval value must be from 1 to 16.  NOTE: The
    // USBPORT.SYS driver only supports high-speed isochronous bInterval
    // values of {1, 2, 3, 4}.
    //
    switch (pipeInfo.Interval) {
    case 1:
        //
        // Transfer period is every microframe (8 times a frame).
        //
        pipeContext->TransferSizePerFrame = pipeContext->TransferSizePerMicroframe * 8;
        break;

    case 2:
        //
        // Transfer period is every 2 microframes (4 times a frame).
        //
        pipeContext->TransferSizePerFrame = pipeContext->TransferSizePerMicroframe * 4;
        break;

    case 3:
        //
        // Transfer period is every 4 microframes (2 times a frame).
        //
        pipeContext->TransferSizePerFrame = pipeContext->TransferSizePerMicroframe * 2;
        break;

    case 4:
        //
        // Transfer period is every 8 microframes (1 times a frame).
        //
        pipeContext->TransferSizePerFrame = pipeContext->TransferSizePerMicroframe;
        break;
    }

    UsbSamp_DbgPrint(1, ("MaxPacketSize = %d, bInterval = %d\n", 
                       pipeInfo.MaximumPacketSize,
                       pipeInfo.Interval));

    UsbSamp_DbgPrint(1, ("TransferSizePerFrame = %d, TransferSizePerMicroframe = %d\n", 
                       pipeContext->TransferSizePerFrame, 
                       pipeContext->TransferSizePerMicroframe));        
    
    return STATUS_SUCCESS;
}


昨天我们省略了#if (NTDDI_VERSION >= NTDDI_WIN8)这分支,我们今天来看一下,一看这个,好像是专为WIN8准备的,USB3.0准备的,不清楚,是猜测的。我们继续往下看:

    //
    // We only use pipe context for super speed isoch and bulk speed bulk endpoints.
    //
    if ((WdfUsbPipeTypeIsochronous == pipeInfo.PipeType)) {

        status = InitializePipeContextForSuperSpeedIsochPipe(DeviceContext,
                    WdfUsbInterfaceGetInterfaceNumber(DeviceContext->UsbInterface),
                    Pipe);

    } else if (WdfUsbPipeTypeBulk == pipeInfo.PipeType) {

        status = InitializePipeContextForSuperSpeedBulkPipe(DeviceContext,
                   WdfUsbInterfaceGetInterfaceNumber(DeviceContext->UsbInterface),
                   Pipe);

    }


这里,通过PIPE的类型,我们用InitializePipeContextForSuperSpeedIsochPipe和InitializePipeContextForSuperSpeedBulkPipe来进行初始化

NTSTATUS
InitializePipeContextForSuperSpeedIsochPipe(
    _In_ PDEVICE_CONTEXT    DeviceContext,
    _In_ UCHAR              InterfaceNumber,
    _In_ WDFUSBPIPE         Pipe
    )
/*++

Routine Description

    This function validates all the isoch related fields in the endpoint descriptor
    to make sure it's in comformance with the spec and Microsoft core stack
    implementation and intializes the pipe context.

    The TransferSizePerMicroframe and TransferSizePerFrame values will be
    used in the I/O path to do read and write transfers.

Return Value:

    NT status value

-*/
{
    WDF_USB_PIPE_INFORMATION    pipeInfo;
    PPIPE_CONTEXT               pipeContext;    
    UCHAR                       endpointAddress;
    PUSB_ENDPOINT_DESCRIPTOR    pEndpointDescriptor;
    PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR pEndpointCompanionDescriptor;
    USHORT                      wMaxPacketSize;
    UCHAR                       bMaxBurst;
    UCHAR                       bMult;
    USHORT                      wBytesPerInterval;


    PAGED_CODE();

    WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
    WdfUsbTargetPipeGetInformation(Pipe, &pipeInfo);
    
    //
    // We use the pipe context only for isoch endpoints.
    //
    if ((WdfUsbPipeTypeIsochronous != pipeInfo.PipeType)) {

        return STATUS_SUCCESS;

    }

    pipeContext = GetPipeContext(Pipe);

    endpointAddress = pipeInfo.EndpointAddress;

    pEndpointDescriptor = GetEndpointDescriptorForEndpointAddress(
                                DeviceContext,
                                InterfaceNumber,
                                endpointAddress,
                                &pEndpointCompanionDescriptor);

    if (pEndpointDescriptor == NULL || pEndpointCompanionDescriptor == NULL ){
        
        UsbSamp_DbgPrint(1, ("pEndpointDescriptor or pEndpointCompanionDescriptor is invalid (NULL)\n"));
        return STATUS_INVALID_PARAMETER;
    
    }

    //
    // For SuperSpeed isoch endpoint, it uses wBytesPerInterval from its
    // endpoint companion descriptor. If bMaxBurst field in its endpoint
    // companion descriptor is greater than zero, wMaxPacketSize must be
    // 1024. If the value in the bMaxBurst field is set to zero then 
    // wMaxPacketSize can have any value from 0 to 1024.
    //
    wBytesPerInterval = pEndpointCompanionDescriptor->wBytesPerInterval;
    wMaxPacketSize = pEndpointDescriptor->wMaxPacketSize;
    bMaxBurst = pEndpointCompanionDescriptor->bMaxBurst;
    bMult = pEndpointCompanionDescriptor->bmAttributes.Isochronous.Mult;

    if (wBytesPerInterval > (wMaxPacketSize * (bMaxBurst + 1) * (bMult + 1))){
                        
        UsbSamp_DbgPrint(1, ("SuperSpeed isochronouse endpoints's wBytesPerInterval value (%d) is greater than wMaxPacketSize * (bMaxBurst+1) * (Mult +1) (%d) \n",
                                wBytesPerInterval, (wMaxPacketSize * (bMaxBurst + 1) * (bMult + 1))));
        return STATUS_INVALID_PARAMETER;

    }

    if (bMaxBurst > 0){

        if (wMaxPacketSize != USB_ENDPOINT_SUPERSPEED_ISO_MAX_PACKET_SIZE){              
                    
            UsbSamp_DbgPrint(1, ("SuperSpeed isochronouse endpoints must have wMaxPacketSize value of %d bytes when bMaxpBurst is %d \n",
                                    USB_ENDPOINT_SUPERSPEED_ISO_MAX_PACKET_SIZE, bMaxBurst));
            return STATUS_INVALID_PARAMETER;

        } 

    } else {

        if (wMaxPacketSize > USB_ENDPOINT_SUPERSPEED_ISO_MAX_PACKET_SIZE){

            UsbSamp_DbgPrint(1, ("SuperSpeed isochronouse endpoints must have wMaxPacketSize value no more than %d bytes when bMaxpBurst is %d \n",
                                    USB_ENDPOINT_SUPERSPEED_ISO_MAX_PACKET_SIZE, bMaxBurst));
            return STATUS_INVALID_PARAMETER;

        } 

    }

 
    //
    // This sample demos how to use wBytesPerInterval from its Endpoint 
    // Companion Descriptor. Actaully, for Superspeed isochronous endpoints,
    // MaximumPacketSize in WDF_USB_PIPE_INFORMATION and USBD_PIPE_INFORMATION
    // is returned with the value of wBytesPerInterval in the endpoint
    // companion descriptor. This is different than the true MaxPacketSize of
    // the endpoint descriptor.
    //
    NT_ASSERT(pipeInfo.MaximumPacketSize == wBytesPerInterval); 
    pipeContext->TransferSizePerMicroframe = wBytesPerInterval;
         
    //
    // Microsoft USB 3.0 stack only supports bInterval value of 1, 2, 3 and 4 
    // (or polling period of 1, 2, 4 and 8).
    // For super-speed isochronous endpoints, the bInterval value is used as
    // the exponent for a 2^(bInterval-1) value expressed in microframes;
    // e.g., a bInterval of 4 means a period of 8 (2^(4-1)) microframes.
    //
    if (pipeInfo.Interval == 0 || pipeInfo.Interval > 4) {

        UsbSamp_DbgPrint(1, ("bInterval value in pipeInfo is invalid (0 or > 4)\n"));
        return STATUS_INVALID_PARAMETER;

    }

    switch (pipeInfo.Interval) {
    case 1:
        //
        // Transfer period is every microframe (8 times a frame).
        //
        pipeContext->TransferSizePerFrame = pipeContext->TransferSizePerMicroframe * 8;
        break;

    case 2:
        //
        // Transfer period is every 2 microframes (4 times a frame).
        //
        pipeContext->TransferSizePerFrame = pipeContext->TransferSizePerMicroframe * 4;
        break;

    case 3:
        //
        // Transfer period is every 4 microframes (2 times a frame).
        //
        pipeContext->TransferSizePerFrame = pipeContext->TransferSizePerMicroframe * 2;
        break;

    case 4:
        //
        // Transfer period is every 8 microframes (1 times a frame).
        //
        pipeContext->TransferSizePerFrame = pipeContext->TransferSizePerMicroframe;
        break;
    }

    UsbSamp_DbgPrint(1, ("MaxPacketSize = %d, bInterval = %d\n", 
                       pipeInfo.MaximumPacketSize,
                       pipeInfo.Interval));

    UsbSamp_DbgPrint(1, ("TransferSizePerFrame = %d, TransferSizePerMicroframe = %d\n", 
                       pipeContext->TransferSizePerFrame, 
                       pipeContext->TransferSizePerMicroframe));        
    
    return STATUS_SUCCESS;
}


这个函数就是前半部分跟我们的HighSpeed和FullSpeed不同,后面基本一样,这里主要调用了GetEndpointDescriptorForEndpointAddress这个函数,我们来看下这个函数:

PUSB_ENDPOINT_DESCRIPTOR
GetEndpointDescriptorForEndpointAddress(
    _In_ PDEVICE_CONTEXT  DeviceContext,
    _In_ UCHAR            InterfaceNumber,
    _In_ UCHAR            EndpointAddress,
    _Out_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR *ppEndpointCompanionDescriptor
    )
/*++

Routine Description:

    The helper routine gets the Endpoint Descriptor matched with EndpointAddress and return
    its Endpoint Companion Descriptor if it has.

Arguments:

    DeviceContext - pointer to the device context which includes configuration descriptor

    InterfaceNumber - InterfaceNumber of selected interface

    EndpointAddress - EndpointAddress of the Pipe

    ppEndpointCompanionDescriptor - pointer to the Endpoint Companioin Descroptor pointer

Return Value:

    Pointer to Endpoint Descriptor

--*/
{

    PUSB_COMMON_DESCRIPTOR                          pCommonDescriptorHeader      = NULL;
    PUSB_CONFIGURATION_DESCRIPTOR                   pConfigurationDescriptor     = NULL;
    PUSB_INTERFACE_DESCRIPTOR                       pInterfaceDescriptor         = NULL;
    PUSB_ENDPOINT_DESCRIPTOR                        pEndpointDescriptor          = NULL;
    PUCHAR                                          startingPosition;
    ULONG                                           index;
    BOOLEAN                                         found                        = FALSE;

    PAGED_CODE();

    pConfigurationDescriptor = DeviceContext->UsbConfigurationDescriptor;

    *ppEndpointCompanionDescriptor = NULL;

    // 
    // Parse the ConfigurationDescriptor (including all Interface and
    // Endpoint Descriptors) and locate a Interface Descriptor which
    // matches the InterfaceNumber, AlternateSetting, InterfaceClass,
    // InterfaceSubClass, and InterfaceProtocol parameters.  
    //
    pInterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(
                                pConfigurationDescriptor,
                                pConfigurationDescriptor,
                                InterfaceNumber,
                                DeviceContext->SelectedAlternateSetting,
                                -1, // InterfaceClass, don't care
                                -1, // InterfaceSubClass, don't care
                                -1  // InterfaceProtocol, don't care
                                );

    if (pInterfaceDescriptor == NULL ) {

        UsbSamp_DbgPrint(1, ("USBD_ParseConfigurationDescriptorEx failed to retrieve Interface Descriptor.\n"));
        goto End;

    }

    startingPosition = (PUCHAR) pInterfaceDescriptor;

    for(index = 0; index < pInterfaceDescriptor->bNumEndpoints; index++) {
    
        pCommonDescriptorHeader = USBD_ParseDescriptors(pConfigurationDescriptor,
                                                        pConfigurationDescriptor->wTotalLength,
                                                        startingPosition,
                                                        USB_ENDPOINT_DESCRIPTOR_TYPE);

        if (pCommonDescriptorHeader == NULL) {

            UsbSamp_DbgPrint(1, ("USBD_ParseDescriptors failed to retrieve SuperSpeed Endpoint Descriptor unexpectedly\n"));
            goto End;
        
        }

        pEndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) pCommonDescriptorHeader;

        //
        // Search an Endpoint Descriptor that matches the EndpointAddress
        //
        if (pEndpointDescriptor->bEndpointAddress == EndpointAddress){
        
            found = TRUE;

            break;
        
        }

        //
        // Skip the current Endpoint Descriptor and search for the next.
        //
        startingPosition = (PUCHAR)pCommonDescriptorHeader + pCommonDescriptorHeader->bLength;
    
    }

    if (found) {
        //
        // Locate the SuperSpeed Endpoint Companion Descriptor associated with the endpoint descriptor
        //
        pCommonDescriptorHeader = USBD_ParseDescriptors(pConfigurationDescriptor,
                                                        pConfigurationDescriptor->wTotalLength,
                                                        pEndpointDescriptor,
                                                        USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR_TYPE);

        if (pCommonDescriptorHeader != NULL) {
                    
            *ppEndpointCompanionDescriptor = 
                (PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR) pCommonDescriptorHeader;
                
        } else {
        
             UsbSamp_DbgPrint(3, ("USBD_ParseDescriptors failed to retrieve SuperSpeed Endpoint Companion Descriptor unexpectedly\n"));
        
        }

    } 

 
End:
    return pEndpointDescriptor;
}


这个函数返回一个端点的描述符,首先调用USBD_ParseConfigurationDescriptorEx函数,分析得到选择的USB接口描述符,从接口描述符的个数中,分析配置描述符,然后得到端点描述符。通过,之前的PIPE中的端点地址和端点描述符中的地址进行比对,如果一样返回。

typedef struct _USB_COMMON_DESCRIPTOR {
  UCHAR  
bLength;
  UCHAR  
bDescriptorType;
} USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR;

typedef struct _USB_CONFIGURATION_DESCRIPTOR { 
  UCHAR  
bLength ;
  UCHAR  
bDescriptorType ;
  USHORT  
wTotalLength ;
  UCHAR  
bNumInterfaces ;
  UCHAR  
bConfigurationValue;
  UCHAR  
iConfiguration ;
  UCHAR  
bmAttributes ;
  UCHAR  
MaxPower ;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR ;

 

typedef struct _USB_ENDPOINT_DESCRIPTOR { 
  UCHAR  
bLength ;
  UCHAR  
bDescriptorType ;
  UCHAR  
bEndpointAddress ;
  UCHAR  
bmAttributes ;
  USHORT  
wMaxPacketSize ;
  UCHAR  
bInterval ;
} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR ;

我们再来看InitializePipeContextForSuperSpeedBulkPipe这个函数:

                     
NTSTATUS
InitializePipeContextForSuperSpeedBulkPipe(
    _In_ PDEVICE_CONTEXT            DeviceContext,
    _In_ UCHAR                      InterfaceNumber,
    _In_ WDFUSBPIPE                 Pipe
    )
/*++

Routine Description:

    This routine initialize pipe's streams context.

Arguments:

    DeviceContext - pointer to device context

    InterfaceNumber - InterfaceNumber of selected interface

    Pipe - Bullk Pipe

Return Value:

    NTSTATUS

--*/

{
    WDF_USB_PIPE_INFORMATION    pipeInfo;
    PPIPE_CONTEXT               pipeContext;
    PUSB_ENDPOINT_DESCRIPTOR    pEndpointDescriptor;
    PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR pEndpointCompanionDescriptor;

    UCHAR               endpointAddress;
    ULONG               maxStreams;
    ULONG               supportedStreams;
    PUSBSAMP_STREAM_INFO pStreamInfo;
    NTSTATUS            status;
    PURB                pUrb = NULL;
    ULONG               i;

    PAGED_CODE();

    WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
    WdfUsbTargetPipeGetInformation(Pipe, &pipeInfo);
    pipeContext = GetPipeContext(Pipe);
    pStreamInfo = &pipeContext->StreamInfo;
    
    pStreamInfo->NumberOfStreams = 0;
    pStreamInfo->StreamList = NULL;
 
    pipeContext->StreamConfigured = FALSE;
    
    //
    // Validate that the endpoint/pipe is of type BULK.
    // Streams are only allowed on a SS BULK endpoint.
    // Also ensure that the bus actually supports streams
    // before proceeding
    //
    if (pipeInfo.PipeType != WdfUsbPipeTypeBulk ||
        DeviceContext->NumberOfStreamsSupportedByController == 0) {
        status = STATUS_SUCCESS;
        goto End;
    }

    endpointAddress = pipeInfo.EndpointAddress;

    pEndpointDescriptor = GetEndpointDescriptorForEndpointAddress(
                                DeviceContext,
                                InterfaceNumber,
                                endpointAddress,
                                &pEndpointCompanionDescriptor);

    if (pEndpointDescriptor != NULL &&
        pEndpointCompanionDescriptor != NULL) {
        
        maxStreams = pEndpointCompanionDescriptor->bmAttributes.Bulk.MaxStreams;

        if (maxStreams == 0) {

            supportedStreams = 0;
        
        } else {
        
            supportedStreams = 1 << maxStreams;
        }

    } else {
    
        UsbSamp_DbgPrint(1, ("Endpoint Descriptor or Endpoint Companion Descriptor is NULL.\n"));
        status = STATUS_INVALID_PARAMETER;
        goto End;
    
    }

    if (supportedStreams == 0) {
        status = STATUS_SUCCESS;
        goto End;
    }

    if (supportedStreams > DeviceContext->NumberOfStreamsSupportedByController) {
        supportedStreams = DeviceContext->NumberOfStreamsSupportedByController;
    }

    pStreamInfo->NumberOfStreams = supportedStreams;

    pStreamInfo->StreamList = ExAllocatePoolWithTag(
                                    NonPagedPool,
                                    supportedStreams * sizeof(USBD_STREAM_INFORMATION),
                                    POOL_TAG);

    if (pStreamInfo->StreamList == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    for(i = 0; i < supportedStreams; i++)
    {
        pStreamInfo->StreamList[i].StreamID = i + 1;
    }

    status = USBD_UrbAllocate(DeviceContext->UsbdHandle, &pUrb);

    if (!NT_SUCCESS(status)){
        pUrb = NULL;
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    pUrb->UrbOpenStaticStreams.Hdr.Length = sizeof(struct _URB_OPEN_STATIC_STREAMS);
    pUrb->UrbOpenStaticStreams.Hdr.Function = URB_FUNCTION_OPEN_STATIC_STREAMS;
    pUrb->UrbOpenStaticStreams.PipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(Pipe);
    pUrb->UrbOpenStaticStreams.NumberOfStreams = pStreamInfo->NumberOfStreams;
    pUrb->UrbOpenStaticStreams.StreamInfoSize = sizeof(USBD_STREAM_INFORMATION);
    pUrb->UrbOpenStaticStreams.Streams = pStreamInfo->StreamList;

    // Send the URB down the stack
    status = WdfUsbTargetPipeSendUrbSynchronously(
                                                  Pipe,
                                                  NULL,
                                                  NULL,
                                                  pUrb                           
                                                  );

    if (NT_SUCCESS(status)) {

         pipeContext->StreamConfigured = TRUE;
  
    }
End:
    if (!NT_SUCCESS(status)) {

        pipeContext->StreamConfigured = FALSE;
        pStreamInfo->NumberOfStreams = 0;

        if (pStreamInfo->StreamList != NULL) {
            ExFreePool(pStreamInfo->StreamList);
            pStreamInfo->StreamList = NULL;
        }

    }

    if(pUrb != NULL) {
        USBD_UrbFree(DeviceContext->UsbdHandle, pUrb);
    }

    return status;
}


前面的代码跟之前的同步传输一样,也是获得端点描述符,只是后面需要目标的管道发送一个URB进行配置,主要是包括stream方面的。我们在这里先看下URB的结构后续还要进行讲解

typedef struct _URB { 
  union {
  struct _URB_HEADER  
UrbHeader;
  struct _URB_SELECT_INTERFACE  
UrbSelectInterface;
  struct _URB_SELECT_CONFIGURATION  
UrbSelectConfiguration;
  struct _URB_PIPE_REQUEST  
UrbPipeRequest;
  struct _URB_FRAME_LENGTH_CONTROL  
UrbFrameLengthControl;
  struct _URB_GET_FRAME_LENGTH  
UrbGetFrameLength;
  struct _URB_SET_FRAME_LENGTH  
UrbSetFrameLength;
  struct _URB_GET_CURRENT_FRAME_NUMBER  
UrbGetCurrentFrameNumber;
  struct _URB_CONTROL_TRANSFER  
UrbControlTransfer;
  struct _URB_BULK_OR_INTERRUPT_TRANSFER  
UrbBulkOrInterruptTransfer;
  struct _URB_ISOCH_TRANSFER  
UrbIsochronousTransfer;
  struct _URB_CONTROL_DESCRIPTOR_REQUEST  
UrbControlDescriptorRequest;
  struct _URB_CONTROL_GET_STATUS_REQUEST  
UrbControlGetStatusRequest;
  struct _URB_CONTROL_FEATURE_REQUEST  
UrbControlFeatureRequest;
  struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST  
UrbControlVendorClassRequest;
  struct _URB_CONTROL_GET_INTERFACE_REQUEST  
UrbControlGetInterfaceRequest;
  struct _URB_CONTROL_GET_CONFIGURATION_REQUEST  
UrbControlGetConfigurationRequest;
  }
} URB, *PURB ;

 

struct _URB_BULK_OR_INTERRUPT_TRANSFER {
  struct _URB_HEADER  
Hdr;
  USBD_PIPE_HANDLE  
PipeHandle;
  ULONG  
TransferFlags;
  ULONG  
TransferBufferLength;
  PVOID  
TransferBuffer;
  PMDL  
TransferBufferMDL;
  struct _URB *
UrbLink;
  .
};

 

这里发送的配置。后续需要了解下WIN8对USB驱动这边的修改。至此,USB设备的配置过程结束了,后续就要进行数据的真正的传输等操作。今天有点感冒,所以今天就到这里,后续继续。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
win10_adb_fastboot驱动_usb_driver是指用于在Windows 10操作系统上安装和管理Android设备的ADB(Android Debug Bridge)和Fastboot驱动,以便进行开发者选项和设备连接。 ADB驱动是Android开发工具包(SDK)中的一个组件,它允许开发者通过电脑上的命令行界面与Android设备进行通信。借助ADB驱动,开发者可以在电脑上安装、调试和测试应用程序,还可以利用ADB命令来获取设备信息、传输文件等。 Fastboot驱动是Android设备上的引导程序,它提供了一种引导设备到Fastboot模式的方式。Fastboot模式是一种拥有高级权限的启动模式,使用Fastboot驱动可以在设备上执行一系列高级操作,如刷写系统分区、解锁引导程序等。 在Windows 10操作系统上安装和配置win10_adb_fastboot驱动_usb_driver一般分为以下几个步骤: 1. 下载ADB驱动程序。例如,可以从官方的Android开发者网站下载最新版本的ADB驱动。 2. 解压下载的驱动文件。将解压后的文件夹保存到一个容易访问的位置。 3. 启动设备管理器。在Windows 10上,可以通过按下Windows键 + X打开快速访问菜单,然后选择“设备管理器”来打开设备管理器。 4. 连接Android设备。使用USB数据线将Android设备连接到电脑上。确保设备处于开发者模式,并已启用USB调试选项。 5. 在设备管理器中找到Android设备。通常,Android设备会出现在“其他设备”或“便携式设备”下面,它可能带有一个黄色的感叹号图标。 6. 右键单击Android设备,选择“更新驱动程序”。 7. 在更新驱动程序向导中,选择“浏览计算机以查找驱动程序软件”。 8. 浏览到之前下载和解压的ADB驱动文件夹,并选择相应的驱动程序。 9. 完成驱动程序的安装过程后,设备管理器中的Android设备应该显示为正常状态。 安装和配置win10_adb_fastboot驱动_usb_driver后,开发者就可以开始使用ADB和Fastboot命令与Android设备进行交互,进一步开发、调试和测试Android应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值