windows USB 驱动开发-URB结构

通用串行总线 (USB) 客户端驱动程序无法直接与其设备通信。 相反,客户端驱动程序会创建请求并将其提交到 USB 驱动程序堆栈进行处理。 在每个请求中,客户端驱动程序提供一个可变长度的数据结构,称为 USB 请求块 (URB) ,URB 结构描述请求的详细信息,还包含有关已完成请求状态的信息。 客户端驱动程序通过 URL 执行所有特定于设备的操作,包括数据传输。 在将请求提交到 USB 驱动程序堆栈之前,客户端驱动程序必须使用有关请求的信息初始化 URB。 对于某些类型的请求,Microsoft 提供帮助程序例程和宏,这些例程和宏分配 URB 结构,并使用客户端驱动程序提供的详细信息填充 URB 结构的必要成员。

每个 URB 都以标准固定大小的标头开头, (_URB_HEADER) ,其用途是标识请求的操作类型。 _URB_HEADER 的 Length 成员指定 URB 的大小(以字节为单位)。 Function 成员必须是一系列系统定义的URB_FUNCTION_XXX常量之一,用于确定所请求的操作类型。 例如,在数据传输的情况下,此成员指示传输的类型。 函数代码URB_FUNCTION_CONTROL_TRANSFER、URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER和URB_FUNCTION_ISOCH_TRANSFER分别指示控制、批量/中断和常时等量传输。 USB 驱动程序堆栈使用 Status 成员返回特定于 USB 的状态代码。

为了提交 URB,客户端驱动程序使用 IOCTL_INTERNAL_USB_SUBMIT_URB 请求,该请求通过 I/O 请求数据包 (IRP) 类型IRP_MJ_INTERNAL_DEVICE_CONTROL传递到设备。

USB 驱动程序堆栈处理完 URB 后,驱动程序堆栈将使用 URB 结构的 Status 成员返回特定于 USB 的状态代码。

KMDF 和 UMDF 驱动程序开发人员应使用相应的框架接口来与 USB 设备通信。 

分配和构建 URB

USB 客户端驱动程序可以使用 Windows 驱动程序模型 (WDM) 驱动程序例程来分配 URB 并格式化 URB,然后再将请求发送到 Microsoft 提供的 USB 驱动程序堆栈。

客户端驱动程序使用 URB 打包 USB 驱动程序堆栈中较低级驱动程序处理请求所需的所有信息。 在 Windows 操作系统中,URB 在 URB 结构中描述。

Microsoft 为 USB 客户端驱动程序提供了例程库。 通过使用这些例程,USB 客户端驱动程序可以为某些指定操作生成 URB 请求,并将其转发到 USB 堆栈中。 如果愿意,可以将客户端驱动程序设计为为支持的操作调用库例程,而不是生成自己的 URB 请求。

Windows 7 及更早版本中的 URB 分配

若要使用适用于 Windows 7 及更早版本的 Windows 的 Windows 驱动程序工具包 (WDK) 中包含的例程发送 USB 请求,客户端驱动程序通常会分配和填充 URB 结构,将 URB 结构与新的 IRP 相关联,并将 IRP 发送到 USB 驱动程序堆栈。

对于某些类型的请求,Microsoft 提供 (由分配 URB 结构的Usbd.sys) 导出的帮助程序例程。 例如, USBD_CreateConfigurationRequestEx 例程为 URB 结构分配内存,为选择配置请求设置 URB 格式,并将 URB 结构的地址返回到客户端驱动程序。 但是,帮助程序例程不能用于所有类型的请求。

Microsoft 还提供了为某些类型的请求设置 URL 格式的宏。 对于这些宏,客户端驱动程序必须通过调用 ExAllocatePoolWithTag 来分配 URB 结构,或者在堆栈上分配 结构。 例如,在客户端驱动程序分配 URB 后,驱动程序可以调用 UsbBuildSelectConfigurationRequest 来格式化选择配置请求的 URB 或清除配置。

对于其他请求,客户端驱动程序必须根据请求类型,通过设置 URB 结构的各个成员来手动分配 和格式化 URB 。

USB 请求完成后,客户端驱动程序必须释放 URB 结构。 如果在堆栈上分配 URB,则 URB 在超出范围时释放。 如果在非分页池中分配 URB,则客户端驱动程序必须调用 ExFreePool 才能释放 URB。

Windows 8中的 URB 分配

WDK for Windows 8 提供了一个新的静态库 Usbdex.lib,用于导出用于分配、格式化和释放 URL 的例程。 此外,还有一种将 URB 与 IRP 相关联的新方法。 新的例程可由面向 Windows Vista 和更高版本的 Windows 的客户端驱动程序调用。

在 Windows Vista 及更高版本上运行的客户端驱动程序必须使用新的例程,以便基础 USB 驱动程序堆栈可以利用某些性能和可靠性改进。 这些改进适用于 Windows 8 中为支持 USB 3.0 设备和主机控制器而引入的新 USB 驱动程序堆栈。 对于 USB 2.0 主控制器,Windows 加载不支持改进的驱动程序堆栈的早期版本。 无论基础驱动程序堆栈的版本或主机控制器支持的协议版本如何,都必须始终调用新的 URB 例程。

在调用任何新例程之前,请确保有一个 USBD 句柄,用于向 USB 驱动程序堆栈注册客户端驱动程序。 若要获取 USBD 句柄, 请调用 USBD_CreateHandle。

WDK 提供以下例程,用于Windows 8。 这些例程在 Usbdlib.h 中定义。

  • USBD_UrbAllocate
  • USBD_IsochUrbAllocate
  • USBD_SelectConfigUrbAllocateAndBuild
  • USBD_SelectInterfaceUrbAllocateAndBuild
  • USBD_UrbFree
  • USBD_AssignUrbToIoStackLocation

前面列表中的分配例程返回指向由 USB 驱动程序堆栈分配的新 URB 结构的指针。 根据 Windows 加载的 USB 驱动程序堆栈的版本, URB 结构可以与不透明的 URB 上下文配对。 URB 上下文是有关 URB 的信息块。 无法查看 URB 标头的内容;这些信息旨在由 USB 驱动程序堆栈在内部使用,以改善 URB 跟踪和处理。 URB 上下文仅由 USB 驱动程序堆栈用于Windows 8。 如果 URB 上下文可用,USB 驱动程序堆栈会使用它使 URB 处理更安全、更高效。 例如,USB 驱动程序堆栈必须确保客户端驱动程序不会提交 URB,然后尝试在第一个请求完成之前重复使用同一 URB。 为了检测此类错误,USB 驱动程序堆栈会将状态信息存储在 URB 上下文中。 如果没有状态信息,USB 驱动程序堆栈将不得不将传入的 URB 与当前正在进行的所有 URB 进行比较。 当客户端驱动程序尝试释放 URB 时,USB 驱动程序堆栈也会使用状态信息。 在释放 URB 之前,USB 驱动程序堆栈会验证状态,以确保 URB 未挂起。

URB 上下文提供用于存储额外 URB 信息的官方机制。 使用 URB 上下文比根据需要分配额外的内存或在 URB 结构的保留成员中存储额外信息更可取。 USB 驱动程序堆栈在非分页池中分配 URB 及其关联的 URB 上下文,以便将来如果需要更大的 URB 上下文,唯一需要调整的是池分配的大小。

URB的结构
typedef struct _URB {
  union {
#if ...
    _URB_HEADER                                     UrbHeader;
#else
    struct _URB_HEADER                              UrbHeader;
#endif
#if ...
    _URB_SELECT_INTERFACE                           UrbSelectInterface;
#else
    struct _URB_SELECT_INTERFACE                    UrbSelectInterface;
#endif
#if ...
    _URB_SELECT_CONFIGURATION                       UrbSelectConfiguration;
#else
    struct _URB_SELECT_CONFIGURATION                UrbSelectConfiguration;
#endif
#if ...
    _URB_PIPE_REQUEST                               UrbPipeRequest;
#else
    struct _URB_PIPE_REQUEST                        UrbPipeRequest;
#endif
#if ...
    _URB_FRAME_LENGTH_CONTROL                       UrbFrameLengthControl;
#else
    struct _URB_FRAME_LENGTH_CONTROL                UrbFrameLengthControl;
#endif
#if ...
    _URB_GET_FRAME_LENGTH                           UrbGetFrameLength;
#else
    struct _URB_GET_FRAME_LENGTH                    UrbGetFrameLength;
#endif
#if ...
    _URB_SET_FRAME_LENGTH                           UrbSetFrameLength;
#else
    struct _URB_SET_FRAME_LENGTH                    UrbSetFrameLength;
#endif
#if ...
    _URB_GET_CURRENT_FRAME_NUMBER                   UrbGetCurrentFrameNumber;
#else
    struct _URB_GET_CURRENT_FRAME_NUMBER            UrbGetCurrentFrameNumber;
#endif
#if ...
    _URB_CONTROL_TRANSFER                           UrbControlTransfer;
#else
    struct _URB_CONTROL_TRANSFER                    UrbControlTransfer;
#endif
#if ...
    _URB_CONTROL_TRANSFER_EX                        UrbControlTransferEx;
#else
    struct _URB_CONTROL_TRANSFER_EX                 UrbControlTransferEx;
#endif
#if ...
    _URB_BULK_OR_INTERRUPT_TRANSFER                 UrbBulkOrInterruptTransfer;
#else
    struct _URB_BULK_OR_INTERRUPT_TRANSFER          UrbBulkOrInterruptTransfer;
#endif
#if ...
    _URB_ISOCH_TRANSFER                             UrbIsochronousTransfer;
#else
    struct _URB_ISOCH_TRANSFER                      UrbIsochronousTransfer;
#endif
#if ...
    _URB_CONTROL_DESCRIPTOR_REQUEST                 UrbControlDescriptorRequest;
#else
    struct _URB_CONTROL_DESCRIPTOR_REQUEST          UrbControlDescriptorRequest;
#endif
#if ...
    _URB_CONTROL_GET_STATUS_REQUEST                 UrbControlGetStatusRequest;
#else
    struct _URB_CONTROL_GET_STATUS_REQUEST          UrbControlGetStatusRequest;
#endif
#if ...
    _URB_CONTROL_FEATURE_REQUEST                    UrbControlFeatureRequest;
#else
    struct _URB_CONTROL_FEATURE_REQUEST             UrbControlFeatureRequest;
#endif
#if ...
    _URB_CONTROL_VENDOR_OR_CLASS_REQUEST            UrbControlVendorClassRequest;
#else
    struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST     UrbControlVendorClassRequest;
#endif
#if ...
    _URB_CONTROL_GET_INTERFACE_REQUEST              UrbControlGetInterfaceRequest;
#else
    struct _URB_CONTROL_GET_INTERFACE_REQUEST       UrbControlGetInterfaceRequest;
#endif
#if ...
    _URB_CONTROL_GET_CONFIGURATION_REQUEST          UrbControlGetConfigurationRequest;
#else
    struct _URB_CONTROL_GET_CONFIGURATION_REQUEST   UrbControlGetConfigurationRequest;
#endif
#if ...
    _URB_OS_FEATURE_DESCRIPTOR_REQUEST              UrbOSFeatureDescriptorRequest;
#else
    struct _URB_OS_FEATURE_DESCRIPTOR_REQUEST       UrbOSFeatureDescriptorRequest;
#endif
#if ...
    _URB_OPEN_STATIC_STREAMS                        UrbOpenStaticStreams;
#else
    struct _URB_OPEN_STATIC_STREAMS                 UrbOpenStaticStreams;
#endif
#if ...
    _URB_GET_ISOCH_PIPE_TRANSFER_PATH_DELAYS        UrbGetIsochPipeTransferPathDelays;
#else
    struct _URB_GET_ISOCH_PIPE_TRANSFER_PATH_DELAYS UrbGetIsochPipeTransferPathDelays;
#endif
  };
} URB, *PURB;
URB 例程更新记录

下表汇总了 URB 例程中的更改。

如何提交 URB

客户端驱动程序使用 I/O 控制代码 (IOCTL) IOCTL 与设备通信,这些请求在 I/O 请求数据包 (IRP) 类型为 IRP_MJ_INTERNAL_DEVICE_CONTROL。 对于特定于设备的请求(如选择配置请求),与 IRP 关联的 USB 请求块 (URB) 中介绍了该请求。 将 URB 与 IRP 相关联并将请求发送到 USB 驱动程序堆栈的过程称为提交 URB。 若要提交 URB,客户端驱动程序必须使用 IOCTL_INTERNAL_USB_SUBMIT_URB 作为设备控制代码。 IOCTL 是提供 I/O 接口的“内部”控制代码之一,客户端驱动程序使用该接口来管理其设备和设备连接到的端口。 用户模式应用程序无权访问这些内部 I/O 接口。 

先决条件

在将请求发送到通用串行总线 (USB) 驱动程序堆栈之前,客户端驱动程序必须根据请求的类型分配 URB 结构和格式,如下步骤:

  • 通过调用 IoAllocateIrp 例程为 URB 分配 IRP。 必须提供接收 IRP 的设备对象的堆栈大小。 在对 IoAttachDeviceToDeviceStack 例程的上一次调用中,你收到了指向该设备对象的指针。 堆栈大小存储在 DEVICE_OBJECT 结构的 StackSize 成员中;
  • 通过调用 IoGetNextIrpStackLocation 获取指向 IRP 的第一个堆栈位置 (IO_STACK_LOCATION) 的指针;
  • 将 IO_STACK_LOCATION 结构的 MajorFunction 成员设置为IRP_MJ_INTERNAL_DEVICE_CONTROL;
  • 将 IO_STACK_LOCATION 结构的 Parameters.DeviceIoControl.IoControlCode 成员设置为IOCTL_INTERNAL_USB_SUBMIT_URB;
  • 将 IO_STACK_LOCATION 结构的 Parameters.Others.Argument1 成员设置为初始化的 URB 结构的地址。 若要将 IRP 关联到 URB,也可以仅当 URB 由 USBD_UrbAllocate、USBD_SelectConfigUrbAllocateAndBuild 或 USBD_SelectInterfaceUrbAllocateAndBuild 分配时才调用 USBD_AssignUrbToIoStackLocation;
  • 通过调用 IoSetCompletionRoutineEx 设置完成例程。如果异步提交 URB,请传递指向调用方实现的完成例程及其上下文的指针。 调用方在其完成例程中释放 IRP。如果要同步提交 IRP,请实现一个完成例程,并在调用 IoSetCompletionRoutineEx 时传递指向该例程的指针。 调用还需要 Context 参数中的初始化 KEVENT 对象。 在完成例程中,将 事件设置为信号状态;
  • 调用 IoCallDriver 将填充的 IRP 转发到设备堆栈中的下一个下一个设备对象。 对于同步调用,在调用 IoCallDriver 后,通过调用 KeWaitForSingleObject 来等待事件对象以获取事件通知;
  • 完成 IRP 后,检查 IRP 的 IoStatus.Status 成员并评估结果。 如果 IoStatus.Status STATUS_SUCCESS,则表示请求成功;
USB 同步提交

以下示例演示如何同步提交 URB。

// The SubmitUrbSync routine submits an URB synchronously.
//
// Parameters:
//      DeviceExtension: Pointer to the caller's device extension. The
//                       device extension must have a pointer to
//                       the next lower device object in the device stacks.  
//
//      Irp: Pointer to an IRP allocated by the caller.
//
//      Urb: Pointer to an URB that is allocated by  USBD_UrbAllocate,
//           USBD_IsochUrbAllocate, USBD_SelectConfigUrbAllocateAndBuild,
//           or USBD_SelectInterfaceUrbAllocateAndBuild.

//      CompletionRoutine: Completion routine.
//
// Return Value:
//
//      NTSTATUS  

NTSTATUS SubmitUrbSync( PDEVICE_EXTENSION DeviceExtension,
                       PIRP Irp,
                       PURB Urb,  
                       PIO_COMPLETION_ROUTINE SyncCompletionRoutine)  

{

    NTSTATUS  ntStatus;  
    KEVENT    kEvent;

    PIO_STACK_LOCATION nextStack;

    // Get the next stack location.
    nextStack = IoGetNextIrpStackLocation(Irp);  

    // Set the major code.
    nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;  

    // Set the IOCTL code for URB submission.
    nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;  

    // Attach the URB to this IRP.
    // The URB must be allocated by USBD_UrbAllocate, USBD_IsochUrbAllocate,
    // USBD_SelectConfigUrbAllocateAndBuild, or USBD_SelectInterfaceUrbAllocateAndBuild.
    USBD_AssignUrbToIoStackLocation (DeviceExtension->UsbdHandle, nextStack, Urb);

    KeInitializeEvent(&kEvent, NotificationEvent, FALSE);

    ntStatus = IoSetCompletionRoutineEx ( DeviceExtension->NextDeviceObject,  
        Irp,  
        SyncCompletionRoutine,  
        (PVOID) &kEvent,  
        TRUE,
        TRUE,
        TRUE);

    if (!NT_SUCCESS(ntStatus))
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IoSetCompletionRoutineEx failed. \n" ));
        goto Exit;
    }

    ntStatus = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);  

    if (ntStatus == STATUS_PENDING)
    {
        KeWaitForSingleObject ( &kEvent,
            Executive,
            KernelMode,
            FALSE,
            NULL);
    }

    ntStatus = Irp->IoStatus.Status;

Exit:

    if (!NT_SUCCESS(ntStatus))
    {
        // We hit a failure condition,
        // We will free the IRP

        IoFreeIrp(Irp);
        Irp = NULL;
    }


    return ntStatus;
}

// The SyncCompletionRoutine routine is the completion routine
// for the synchronous URB submit request.
//
// Parameters:
//
//      DeviceObject: Pointer to the device object.
//      Irp:          Pointer to an I/O Request Packet.
//      CompletionContext: Context for the completion routine.
//
// Return Value:
//
//      NTSTATUS  

NTSTATUS SyncCompletionRoutine ( PDEVICE_OBJECT DeviceObject,
                                PIRP           Irp,
                                PVOID          Context)
{
    PKEVENT kevent;

    kevent = (PKEVENT) Context;

    if (Irp->PendingReturned == TRUE)
    {
        KeSetEvent(kevent, IO_NO_INCREMENT, FALSE);
    }

    KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Request completed. \n" ));


    return STATUS_MORE_PROCESSING_REQUIRED;
}

USB 异步提交
以下示例演示如何异步提交 URB。

// The SubmitUrbASync routine submits an URB asynchronously.
//
// Parameters:
//
// Parameters:
//      DeviceExtension: Pointer to the caller's device extension. The
//                       device extension must have a pointer to
//                       the next lower device object in the device stacks.  
//
//      Irp: Pointer to an IRP allocated by the caller.
//
//      Urb: Pointer to an URB that is allocated by  USBD_UrbAllocate,
//           USBD_IsochUrbAllocate, USBD_SelectConfigUrbAllocateAndBuild,
//           or USBD_SelectInterfaceUrbAllocateAndBuild.

//      CompletionRoutine: Completion routine.
//
//      CompletionContext: Context for the completion routine.
//
//
// Return Value:
//
//      NTSTATUS

NTSTATUS SubmitUrbASync ( PDEVICE_EXTENSION DeviceExtension,
                         PIRP Irp,
                         PURB Urb,  
                         PIO_COMPLETION_ROUTINE CompletionRoutine,  
                         PVOID CompletionContext)  
{
    // Completion routine is required if the URB is submitted asynchronously.
    // The caller's completion routine releases the IRP when it completes.


    NTSTATUS ntStatus = -1;  

    PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(Irp);  

    // Attach the URB to this IRP.
    nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;  

    // Attach the URB to this IRP.
    nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;  

    // Attach the URB to this IRP.
    (void) USBD_AssignUrbToIoStackLocation (DeviceExtension->UsbdHandle, nextStack, Urb);  

    // Caller's completion routine will free the irp when it completes.
    ntStatus = IoSetCompletionRoutineEx ( DeviceExtension->NextDeviceObject,
        Irp,  
        CompletionRoutine,  
        CompletionContext,  
        TRUE,
        TRUE,
        TRUE);

    if (!NT_SUCCESS(ntStatus))
    {
        goto Exit;
    }

    (void) IoCallDriver(DeviceExtension->NextDeviceObject, Irp);

Exit:
    if (!NT_SUCCESS(ntStatus))
    {
        // We hit a failure condition,
        // We will free the IRP

        IoFreeIrp(Irp);
        Irp = NULL;
    }

    return ntStatus;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/763367.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

zdppy_api+vue3+antd开发前后端分离的tab卡片

后端代码 import api import uploadsave_dir "uploads"async def rand_content(request):key api.req.get_query(request, "key")return api.resp.success(f"{key} " * 100)app api.Api(routes[api.resp.get("/", rand_content),u…

2024科技文化节程序设计竞赛

补题链接 https://www.luogu.com.cn/contest/178895#problems A. 签到题 忽略掉大小为1的环&#xff0c;答案是剩下环的大小和减环的数量 #include<bits/stdc.h> #include<iostream> #include<cstdio> #include<vector> #include<map> #incl…

Victor CMS v1.0 SQL 注入漏洞(CVE-2022-28060)

前言 CVE-2022-28060 是 Victor CMS v1.0 中的一个SQL注入漏洞。该漏洞存在于 /includes/login.php 文件中的 user_name 参数。攻击者可以通过发送特制的 SQL 语句&#xff0c;利用这个漏洞执行未授权的数据库操作&#xff0c;从而访问或修改数据库中的敏感信息。 漏洞详细信…

mac安装达梦数据库

参考&#xff1a;mac安装达梦数据库​​​​​​ 实践如下&#xff1a; 1、下载达梦Docker镜像文件 同参考链接 2、导入镜像 镜像可以随便放在某个目录&#xff0c;相当于安装包&#xff0c;导入后就没有作用了。 查找达梦镜像名称&#xff1a;dm8_20240613_rev229704_x86…

第11章 规划过程组(11.6规划进度管理)

第11章 规划过程组&#xff08;二&#xff09;11.6规划进度管理&#xff0c;在第三版教材第385页&#xff1b;#软考中级##中级系统集成项目管理师# 文字图片音频方式 第一个知识点&#xff1a;主要输出 1、进度管理计划 准确度 定义活动持续时间估算的可接受区间&#xff0…

Pycharm常用快捷键整理

1&#xff0c;格式化代码 【ctrlAltL】 写代码的时候会发现有很多黄色的波浪号&#xff0c;这个时候可以点击任意黄色波浪号的代码&#xff0c;然后按下【Ctrl Alt L】进行代码格式化 2&#xff0c;快速往返 ctrll Alt ⬅ &#xff0c;表示查看上一步调用函数位置&#xff0…

Oracle 视图、存储过程、函数、序列、索引、同义词、触发器

优质博文&#xff1a;IT-BLOG-CN 一、视图 从表中抽出的逻辑上相关的数据集合&#xff0c;视图是一种虚表&#xff0c;视图是建立在已有表的基础之上&#xff0c;视图赖以建立的这些表称为基表。向视图提供数据的是 SELECT语句&#xff0c;可以将视图理解为存储起来的SELECT语…

KV260视觉AI套件--PYNQ-DPU-Resnet50

目录 1. 简介 2. 代码解析 3. 全部代码展示 4. 总结 1. 简介 Resnet50 一种深度卷积神经网络&#xff08;CNN&#xff09;&#xff0c;它由50层构成。这种网络特别设计用于图像识别任务&#xff0c;并且在2015年的ImageNet大规模视觉识别挑战赛&#xff08;ILSVRC&#x…

notepad++安装并打开json文件

1、notepad安装 1、首先下载Notepad.exe 2、选择简体中文安装 点击下一步 点击“我接受” 选择安装目录&#xff0c;进行下一步安装 默认下一步 选择安装 等待安装完成 点击完成 2、保存json文件 复制返回结果 先把返回结果复制出来。保存到text里面 把文件另存为json格式 3、…

Mac搭建anaconda环境并安装深度学习库

1. 下载anaconda安装包 根据自己的操作系统不同&#xff0c;选择不同的安装包Anaconda3-2024.06-1-MacOSX-x86_64.pkg&#xff0c;我用的还是旧的intel所以下载这个&#xff0c;https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/&#xff0c;如果mac用的是M1&#xff0…

通过百度文心智能体创建STM32编程助手-实操

一、前言 文心智能体平台AgentBuilder 是百度推出的基于文心大模型的智能体&#xff08;Agent&#xff09;平台&#xff0c;支持广大开发者根据自身行业领域、应用场景&#xff0c;选取不同类型的开发方式&#xff0c;打造大模型时代的产品能力。开发者可以通过 prompt 编排的…

拍摄的vlog视频画质模糊怎么办?视频画质高清修复

在短视频逐渐成为主流的今天&#xff0c;许多朋友都会通过vlog的形式记录下自己的生活。但我们会发现&#xff0c;自己拍摄的视频与专业博主拍摄的视频&#xff0c;在画质上就会有所差别&#xff0c;拍摄的vlog视频画质模糊不清晰怎么办&#xff1f; 拍摄的vlog视频画质模糊怎么…

昇思第6天

函数式自动微分 神经网络的训练主要使用反向传播算法&#xff0c;模型预测值&#xff08;logits&#xff09;与正确标签&#xff08;label&#xff09;送入损失函数&#xff08;loss function&#xff09;获得loss&#xff0c;然后进行反向传播计算&#xff0c;求得梯度&#…

推荐算法学习笔记2.2:基于深度学习的推荐算法-基于特征交叉组合+逻辑回归思路的深度推荐算法-Deep Crossing模型

Deep Crossing模型&#xff08;微软&#xff0c;搜索引擎&#xff0c;广告推荐&#xff09; 前置知识&#xff1a;推荐算法学习笔记1.3:传统推荐算法-逻辑回归算法&#xff0c;推荐算法学习笔记1.4:传统推荐算法-自动特征的交叉解决方案&#xff1a;FM→FFM 本文含残差块反向传…

人工智能--目标检测

欢迎来到 Papicatch的博客 文章目录 &#x1f349;引言 &#x1f349;概述 &#x1f348;目标检测的主要流程通常包括以下几个步骤 &#x1f34d;数据采集 &#x1f34d;数据预处理 &#x1f34d;特征提取 &#x1f34d;目标定位 &#x1f34d;目标分类 &#x1f348;…

mac软件卸载后的残留文件删除 mac如何卸载应用程序

很多人都不知道&#xff0c;mac使用系统方式卸载后会有残留文件未被删除&#xff0c;久而久之就会占用大量的磁盘空间。今天小编就来教大家如何删除mac软件卸载后的残留文件&#xff0c;如果你想不留痕迹的删除&#xff0c;mac又该如何正确卸载应用程序&#xff0c;本文将一一为…

整合、速通 版本控制器-->Git 的实际应用

目录 版本控制器 -- Git1、Git 和 SVN 的区别2、Git 的卸载和安装2-1&#xff1a;Git 卸载1、先查下原本的Git版本2、删除环境变量3、控制面板卸载 Git 2-2&#xff1a;Git 下载安装1、官网下载2、详细安装步骤3、安装成功展示 3、Git 基础知识3-1&#xff1a;基本的 Linux 命令…

通俗易懂的chatgpg的原理简介

目录 一、深度学习与语言模型 二、ChatGPT训练三步走 三、情景学习与思维链 四、修改提示语优化结果 五、能力评估和注意问题 六.算法原理 简介&#xff1a; ChatGPT的人工智能原理主要基于深度学习技术&#xff0c;特别是大规模的预训练语言模型和Transformer结构。Cha…

SpringCloud_Eureka注册中心

概述 Eureka是SpringCloud的注册中心。 是一款基于REST的服务治理框架&#xff0c;用于实现微服务架构中的服务发现和负载均衡。 在Eureka体系中&#xff0c;有两种角色: 服务提供者和服务消费者。 服务提供者将自己注册到Eureka服务器&#xff0c;服务消费者从Eureka服务器中…

使用Qt制作一个简单的界面

1、创建工程 步骤一&#xff1a; 步骤二&#xff1a; 步骤三&#xff1a; 选择 build system&#xff0c;有qmake、CMake 和 Qbs 三个选项。 CMake 很常用&#xff0c;功能也很强大&#xff0c;许多知名的项目都是用它&#xff0c;比如 OpenCV 和 VTK&#xff0c;但它的语法繁…