windows USB 设备驱动开发-开发Type C接口的驱动程序(二)

编写 USB Type C 连接器驱动程序

在以下情况下,需要编写 USB Type-C 连接器驱动程序:

  • 如果 USB Type-C 硬件能够处理电源输送 (PD) 状态机。 否则,请考虑编写 USB Type C 端口控制器驱动程序; 
  • 如果硬件没有嵌入式控制器。 否则,加载 Microsoft 提供的内置驱动程序,UcmUcsi.sys,或为非 ACPI 传输编写 UCSI 客户端驱动程序 ;
类扩展和客户端驱动程序使用的 UCM 对象

下面介绍 USB 连接器管理器 (UCM) ,用于管理 USB Type-C 连接器和连接器驱动程序的预期行为。

UCM 是使用 WDF 类扩展客户端驱动程序模型设计的。 UcmCx类扩展是 Microsoft 提供的 WDF 驱动程序,它提供客户端驱动程序可以调用这些接口来报告有关连接器的信息。 UCM 客户端驱动程序使用连接器的硬件接口,并使类扩展能够识别连接器上发生的事件。 相反,类扩展调用客户端驱动程序为响应操作系统事件而实现的回调函数。

若要在系统上启用 USB Type-C 连接器,必须编写客户端驱动程序。

准备阶段

在开发 计算机上安装最新的 Windows 驱动程序工具包 (WDK) 。 该工具包具有编写 UCM 客户端驱动程序所需的头文件和库,具体而言,你需要:

  • 库UcmCxstub.lib,该库转换客户端驱动程序发出的调用,并将其传递给 UcmCx;
  • 头文件 UcmCx.h;

可以编写在用户模式或内核模式下运行的 UCM 客户端驱动程序。 对于用户模式,它与 UMDF 2.x 库绑定;对于内核模式,则为 KMDF 1.15。 对于任一模式,编程接口都是相同的。

确定客户端驱动程序是否支持 USB Type-C 连接器和 USB 电源输送的高级功能。

此支持使你能够构建具有 USB Type-C 连接器、USB Type-C 扩展坞和附件以及 USB Type-C 充电器的 Windows 设备。 客户端驱动程序报告连接器事件,这些事件允许操作系统针对系统中的 USB 和功耗实施策略。

  • 使用 USB Type-C 连接器在目标计算机或Windows 10 移动版上安装桌面版 (家庭版、专业版、企业) 版和教育版的Windows 10;
  • 熟悉 UCM 及其与其他 Windows 驱动程序的交互方式;
  • 熟悉 Windows Driver Foundation (WDF) ;
UCM 类扩展提供的服务摘要

UCM 类扩展使操作系统随时了解数据和电源角色、充电级别以及协商的 PD 协定的更改。 当客户端驱动程序与硬件交互时,它必须在发生这些更改时通知类扩展。 类扩展提供了一组方法,客户端驱动程序可以使用这些方法发送本主题 () 中讨论的通知。 以下是提供的服务:

数据角色配置

在 USB Type C 系统上, (主机或功能) 的数据角色取决于连接器的 CC 引脚的状态。 客户端驱动程序读取 CC 线路端口控制器的状态,以确定端口是否已解析为面向上游的端口 (UFP) 或面向下游的端口 (UFP) 。 它将该信息报告给类扩展,以便它可以向 USB 角色切换驱动程序报告当前角色。

 备注 USB 角色切换驱动程序用于Windows 10 移动版系统。 在桌面版系统的Windows 10上,类扩展和角色切换驱动程序之间的通信是可选的。 此类系统可能不使用双角色控制器,在这种情况下,不使用角色切换驱动程序。

电源角色和充电

客户端驱动程序读取 USB Type C 当前播发,或与合作伙伴连接器协商 PD 电源合同。

  • 在Windows 10 移动版系统上,选择适当的充电器的决定是由软件辅助的。 客户端驱动程序将协定信息报告给类扩展,以便它可以将充电级别发送到充电仲裁驱动程序 (CAD.sys) 。 CAD 选择要使用的当前电量并将充电级别信息转发到电池子系统。
  • 在桌面版系统的Windows 10上,硬件选择适当的充电器。 客户端驱动程序可以选择获取该信息并将其转发到类扩展。 或者,该逻辑可能由其他驱动程序实现。
数据和电源角色更改

协商 PD 合同后,数据角色和权力角色可能会更改。 该更改可能由客户端驱动程序或合作伙伴连接器启动。 客户端驱动程序向类扩展报告该信息,以便它可以相应地重新配置内容。

数据和/或电源角色更新

操作系统可能会确定当前数据角色不正确。 在这种情况下,类扩展会调用驱动程序的回调函数来执行必要的角色交换操作。

Microsoft 提供的 USB Type C 策略管理器监视 USB Type C 连接器的活动。 Windows 版本 1809 引入了一组编程接口,可用于将客户端驱动程序写入策略管理器。 客户端驱动程序可以参与 USB Type C 连接器的策略决策。 使用此集,可以选择编写内核模式导出驱动程序或用户模式驱动程序。 

客户端驱动程序的预期行为

客户端驱动程序负责执行以下任务:

  • 检测抄送行上的更改,并确定合作伙伴的类型,例如 UFP、DFP 等。 为此,驱动程序必须实现 USB Type C 规范中定义的完整 Type-C 状态机;
  • 根据在 CC 线上检测到的方向配置 Mux。 这包括打开 PD 发送器/接收器以及处理和响应 PD 消息。 为此,驱动程序必须实现 USB 电源交付 2.0 规范中定义的完整 PD 接收器和发射器状态机;
  • 制定 PD 策略决策,例如将合同协商 (为源或接收器) 、角色交换等。 客户端驱动程序负责确定最合适的协定。
  • 播发和协商备用模式,如果检测到备用模式,则配置 Mux。 客户端驱动程序负责决定要协商的备用模式;
  • 通过连接器控制 VBus/VConn;
1. (UCMCONNECTOR) 初始化 UCM 连接器对象

UCM 连接器对象 (UCMCONNECTOR) 表示 USB Type C 连接器,是 UCM 类扩展和客户端驱动程序之间的main句柄。 对象跟踪连接器的操作模式和电源功能。

下面是客户端驱动程序检索连接器的 UCMCONNECTOR 句柄的序列摘要。 在驱动程序的 中执行这些任务

1.1. 通过将引用传递给 UCM_MANAGER_CONFIG 结构来调用 UcmInitializeDevice。 在调用 WdfDeviceCreate 之前,驱动程序必须在 EVT_WDF_DRIVER_DEVICE_ADD 回调函数中调用此方法。

1.2. 在 UCM_CONNECTOR_TYPEC_CONFIG 结构中指定 USB Type-C 连接器的初始化参数。 这包括连接器的操作模式,无论是面向下游的端口、面向上游端口,还是支持双重角色。 它还指定连接器为电源时的 USB Type C 电流级别。 可以设计 USB Type-C 连接器,使其可以充当 3.5 毫米音频插孔。 如果硬件支持该功能,则必须相应地初始化连接器对象。

在 结构中,还必须注册客户端驱动程序的回调函数以处理数据角色。

此回调函数与连接器对象相关联,连接器对象由 UCM 类扩展调用。 此函数必须由客户端驱动程序实现。

EVT_UCM_CONNECTOR_SET_DATA_ROLE 在附加到合作伙伴连接器时,将连接器的数据角色交换为指定角色。

1.3. 如果客户端驱动程序希望支持 PD,即处理连接器的 Power Delivery 2.0 硬件实现,则还必须初始化指定 PD 初始化参数 的 UCM_CONNECTOR_PD_CONFIG 结构。 这包括电源流,无论连接器是电源接收器还是电源。

在 结构中,还必须注册客户端驱动程序的回调函数来处理电源角色。

此回调函数与连接器对象相关联,连接器对象由 UCM 类扩展调用。 此函数必须由客户端驱动程序实现。

EVT_UCM_CONNECTOR_SET_POWER_ROLE 在连接到合作伙伴连接器时,将连接器的电源角色设置为指定角色。

1.4. 调用 UcmConnectorCreate 并检索连接器的 UCMCONNECTOR 句柄。 请确保在客户端驱动程序通过调用 WdfDeviceCreate 创建框架设备对象后调用此方法。 此调用的适当位置可以位于驱动程序 EVT_WDF_DEVICE_PREPARE_HARDWARE 或 EVT_WDF_DEVICE_D0_ENTRY。

EVT_UCM_CONNECTOR_SET_DATA_ROLE     EvtSetDataRole;NTSTATUS
EvtDevicePrepareHardware(WDFDEVICE Device,WDFCMRESLIST ResourcesRaw,WDFCMRESLIST ResourcesTranslated)
{NTSTATUS status = STATUS_SUCCESS;PDEVICE_CONTEXT devCtx;UCM_MANAGER_CONFIG ucmCfg;UCM_CONNECTOR_CONFIG connCfg;UCM_CONNECTOR_TYPEC_CONFIG typeCConfig;UCM_CONNECTOR_PD_CONFIG pdConfig;WDF_OBJECT_ATTRIBUTES attr;PCONNECTOR_CONTEXT connCtx;UNREFERENCED_PARAMETER(ResourcesRaw);UNREFERENCED_PARAMETER(ResourcesTranslated);TRACE_FUNC_ENTRY();devCtx = GetDeviceContext(Device);if (devCtx->Connector){goto Exit;}//// Initialize UCM Manager//UCM_MANAGER_CONFIG_INIT(&ucmCfg);status = UcmInitializeDevice(Device, &ucmCfg);if (!NT_SUCCESS(status)){TRACE_ERROR("UcmInitializeDevice failed with %!STATUS!.",status);goto Exit;}TRACE_INFO("UcmInitializeDevice() succeeded.");//// Create a USB Type-C connector #0 with PD//UCM_CONNECTOR_CONFIG_INIT(&connCfg, 0);UCM_CONNECTOR_TYPEC_CONFIG_INIT(&typeCConfig,UcmTypeCOperatingModeDrp,UcmTypeCCurrentDefaultUsb | UcmTypeCCurrent1500mA | UcmTypeCCurrent3000mA);typeCConfig.EvtSetDataRole = EvtSetDataRole;UCM_CONNECTOR_PD_CONFIG_INIT(&pdConfig, UcmPowerRoleSink | UcmPowerRoleSource);connCfg.TypeCConfig = &typeCConfig;connCfg.PdConfig = &pdConfig;WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, CONNECTOR_CONTEXT);status = UcmConnectorCreate(Device, &connCfg, &attr, &devCtx->Connector);if (!NT_SUCCESS(status)){TRACE_ERROR("UcmConnectorCreate failed with %!STATUS!.",status);goto Exit;}connCtx = GetConnectorContext(devCtx->Connector);UcmEventInitialize(&connCtx->EventSetDataRole);TRACE_INFO("UcmConnectorCreate() succeeded.");Exit:TRACE_FUNC_EXIT();return status;
}
2.报告合作伙伴连接器附加事件

检测到与合作伙伴连接器的连接时,客户端驱动程序必须调用 UcmConnectorTypeCAttach 。 此调用通知 UCM 类扩展,这会进一步通知操作系统。 此时,系统可能会开始在 USB Type C 级别充电。

UCM 类扩展还会通知 USB 角色切换驱动程序 (URS) 。 根据合作伙伴的类型,URS 在Host角色或功能角色中配置控制器。 在调用此方法之前,请确保系统已正确配置。 否则,如果系统处于功能角色,它将以不正确的速度连接 (高速而不是 SuperSpeed) 。

UCM_CONNECTOR_TYPEC_ATTACH_PARAMS attachParams;UCM_CONNECTOR_TYPEC_ATTACH_PARAMS_INIT(&attachParams,UcmTypeCPortStateDfp);attachParams.CurrentAdvertisement = UcmTypeCCurrent1500mA;status = UcmConnectorTypeCAttach(Connector,&attachParams);if (!NT_SUCCESS(status)){TRACE_ERROR("UcmConnectorTypeCAttach() failed with %!STATUS!.",status);goto Exit;}TRACE_INFO("UcmConnectorTypeCAttach() succeeded.");
3. 报告 USB Type C 播发更改

在初始附加事件中,合作伙伴连接器发送当前播发。 如果播发指定合作伙伴连接器的当前级别,则合作伙伴是面向 USB Type C 的端口。 否则,播发指定本地连接器的当前级别,由本地连接器 UCMCONNECTOR 句柄表示。 此初始播发可能会在连接的生存期内更改。 这些更改必须由客户端驱动程序监视。

如果本地连接器是电源接收器,并且当前播发发生了更改,则客户端驱动程序必须检测当前播发中的更改,并将其报告给类扩展。 在Windows 10 移动版系统上,CAD.sys 和电池子系统使用该信息来调整从源中抽取的电流量。 若要向类扩展报告当前级别的更改,客户端驱动程序必须调用 UcmConnectorTypeCCurrentAdChanged。

4. 报告新的协商 PD 合同

如果连接器支持 PD,在初始附加事件之后,连接器及其合作伙伴连接器之间传输了 PD 消息。 在两个合作伙伴之间,协商 PD 合同,确定连接器可以绘制或允许合作伙伴绘制的当前级别。 每次 PD 协定更改时,客户端驱动程序都必须调用这些方法来向类扩展报告更改。

  • 每当客户端驱动程序获取源功能播发 (未经请求或从合作伙伴) 时,都必须调用这些方法。 仅当合作伙伴是源时,本地连接器 (接收器) 从合作伙伴获取未经请求的广告。 此外,即使合作伙伴当前是接收器,本地连接器也可以显式请求能够成为源的合作伙伴的源功能。 通过向合作伙伴发送 Get_Source_Caps 消息来完成交换。

UcmConnectorPdPartnerSourceCaps 用于报告合作伙伴连接器播发的源功能。
UcmConnectorPdConnectionStateChanged 用于报告合同的详细信息。 该协定在 Power Delivery 2.0 规范中定义的请求数据对象中描述。

  • 相反,每次本地连接器 (源) 向合作伙伴播发源功能时,客户端驱动程序都必须调用这些方法。 此外,当本地连接器收到来自合作伙伴 的Get_Source_Caps 消息时,它必须使用本地连接器的源功能进行响应。

UcmConnectorPdSourceCaps ,用于将系统播发的源功能报告给合作伙伴连接器。
UcmConnectorPdConnectionStateChanged 报告当前协商的 PD 协定的连接功能。

5. 报告电池充电状态

如果充电级别不足,客户端驱动程序可以通知 UCM 类扩展。 类扩展将此信息报告给操作系统。 系统使用该信息向用户显示充电器未以最佳方式为系统充电的通知。 可以通过以下方法报告充电状态:

  • UcmConnectorChargingStateChanged
  • UcmConnectorTypeCAttach
  • UcmConnectorPdConnectionStateChanged

这些方法指定充电状态。 如果报告的级别为 UcmChargingStateSlowCharging 或 UcmChargingStateTrickleCharging 。

6. 报告PR_Swap/DR_Swap事件

如果连接器收到电源角色 (PR_Swap) 或数据角色 (DR_Swap) 交换来自合作伙伴的消息,则客户端驱动程序必须通知 UCM 类扩展。

  • UcmConnectorDataDirectionChanged

处理 PD DR_Swap消息后调用此方法。 完成此调用后,操作系统会将新角色报告给 URS,这会删除现有角色驱动程序并加载新角色的驱动程序。

  • UcmConnectorPowerDirectionChanged

在处理 PD PR_Swap消息后调用此方法。 PR_Swap后,需要重新谈判 PD 协定。 客户端驱动程序必须通过调用 步骤 4 中所述的方法来报告 PD 协定协商。

7. 实现回调函数以处理电源和数据角色交换请求

UCM 类扩展可能会收到更改连接器的数据或电源方向的请求。 在这种情况下,如果连接器实现 PD) ,它将 (调用客户端驱动程序实现EVT_UCM_CONNECTOR_SET_DATA_ROLE 和EVT_UCM_CONNECTOR_SET_POWER_ROLE 回调函数。 客户端驱动程序之前在调用 UcmConnectorCreate 时注册了这些函数。

客户端驱动程序使用硬件接口执行角色交换操作。

  • EVT_UCM_CONNECTOR_SET_DATA_ROLE

在回调实现中,客户端驱动程序应:

  1. 向端口伙伴发送 PD DR_Swap消息。
  2. 调用 UcmConnectorDataDirectionChanged 以通知类扩展消息序列已成功完成或未成功。
    EVT_UCM_CONNECTOR_SET_DATA_ROLE     EvtSetDataRole;NTSTATUS
    EvtSetDataRole(UCMCONNECTOR  Connector,UCM_TYPE_C_PORT_STATE DataRole)
    {PCONNECTOR_CONTEXT connCtx;TRACE_INFO("EvtSetDataRole(%!UCM_TYPE_C_PORT_STATE!) Entry", DataRole);connCtx = GetConnectorContext(Connector);TRACE_FUNC_EXIT();return STATUS_SUCCESS;
    }

在回调实现中,客户端驱动程序应:

  1. 向端口合作伙伴发送 PD PR_Swap消息;
  2. 调用 UcmConnectorPowerDirectionChanged 以通知类扩展消息序列已成功完成或未成功;
    EVT_UCM_CONNECTOR_SET_POWER_ROLE     EvtSetPowerRole;NTSTATUS
    EvtSetPowerRole(UCMCONNECTOR Connector,UCM_POWER_ROLE PowerRole)
    {PCONNECTOR_CONTEXT connCtx;TRACE_INFO("EvtSetPowerRole(%!UCM_POWER_ROLE!) Entry", PowerRole);connCtx = GetConnectorContext(Connector);//PR_Swap operation.TRACE_FUNC_EXIT();return STATUS_SUCCESS;
    }

客户端驱动程序可以异步调用 UcmConnectorDataDirectionChanged 和 UcmConnectorPowerDirectionChanged ,这并非来自回调线程。 在典型的实现中, 类扩展调用回调函数,导致客户端驱动程序启动硬件事务以发送消息。 事务完成后,硬件会通知驱动程序。 驱动程序调用这些方法以通知类扩展。

8.报告合作伙伴连接器分离事件

当与合作伙伴连接器的连接结束时,客户端驱动程序必须调用 UcmConnectorTypeCDetach 。 此调用通知 UCM 类扩展,这会进一步通知操作系统。

用例示例:连接到电脑的移动设备

当运行 Windows 10 移动版 的设备通过 USB Type-C 连接连接到运行 Windows 10 桌面版的电脑时,操作系统将确保移动设备是面向上游的端口 (UFP) ,因为 MTP 仅在该方向上工作。 在此方案中,数据角色更正的顺序如下:

  1. 在移动设备上运行的客户端驱动程序通过调用 UcmConnectorTypeCAttach 报告附加事件,并将合作伙伴连接器报告为面向下游的端口 (UFP) ;
  2. 客户端驱动程序通过调用 UcmConnectorPdPartnerSourceCaps 和 UcmConnectorPdConnectionStateChanged 报告 PD 协定;
  3. UCM 类扩展通知 USB 设备端驱动程序,导致这些驱动程序响应来自主机的枚举。 操作系统信息通过 USB 交换;
  4. UCM 类扩展 UcmCx 调用客户端驱动程序的回调函数以更改角色: EVT_UCM_CONNECTOR_SET_DATA_ROLE 和 EVT_UCM_CONNECTOR_SET_POWER_ROLE;

如果两个Windows 10 移动版设备相互连接,则不会执行角色交换,并且通知用户该连接不是有效的连接。

编写 USB Type C 策略管理器客户端驱动程序

Microsoft 提供的 USB Type C 策略管理器监视 USB Type C 连接器的活动。 Windows 版本 1809 引入了一组编程接口,可用于在本文中将客户端驱动程序写入策略管理器称为 PM 客户端驱动程序 。 客户端驱动程序可以参与 USB Type C 连接器的策略决策。 使用此集,可以选择编写内核模式导出驱动程序或用户模式驱动程序。

策略管理器从 USB 连接器管理器 (UCM) 、USB 主机控制器和 USB 功能以及 PM 客户端驱动程序获取和协调信息。 需要 UI 通知时,策略管理器会将请求发送到系统 Shell。

PM API 在 Usbpmapi.h 标头中声明。

1:客户端注册
  1. 客户端驱动程序调用 UsbPm_Register 来注册驱动程序的回调函数;
  2. 客户端驱动程序等待来自策略管理器的事件。成功的 UsbPm_Register 调用不保证客户端驱动程序已请求访问权限。 策略管理器准备就绪后,驱动程序 EVT_USBPM_EVENT_CALLBACK 使用 PolicyManagerArrival 作为指示授予的实际访问权限的事件数据进行调用;
  3. UsbPm_Register调用返回注册句柄。客户端驱动程序可能在 UsbPm_Register 返回之前收到 EVT_USBPM_EVENT_CALLBACK ;
2:通知到达
  1. 当 UCMCX 设备到达时,POlicy Manager 会收到通知,并跟踪所有中心句柄以及每个中心上所有连接器的属性和状态;
  2. 使用 HubArrivalRemoval 作为事件数据调用客户端驱动程序的EVT_USBPM_EVENT_CALLBACK,调用还包含中心句柄;
  3. 在客户端驱动程序的 EVT_USBPM_EVENT_CALLBACK 实现中,驱动程序调用 UsbPm_RetrieveHubProperties 以获取中心上的连接器数,然后调用 UsbPm_RetrieveConnectorProperties 和 UsbPm_RetrieveConnectorState 以获取有关每个连接器的详细信息;
3:连接器状态更改
  1. 由于连接器状态更改(例如,Type-C 附加/分离、PD 协定协商),策略管理器会更新每个连接器的状态信息;
  2. 使用 ConnectorStateChange 作为事件数据调用客户端驱动程序的EVT_USBPM_EVENT_CALLBACK。 调用还包含连接器句柄;
  3. 客户端驱动程序的完成例程也会被调用,并相应地执行操作;
  4. 在客户端驱动程序的 EVT_USBPM_EVENT_CALLBACK 实现中,驱动程序调用 UsbPm_RetrieveConnectorProperties。 通过使用给定的连接器句柄,驱动程序获取最新的连接器状态,对其进行检查,并可能决定更新其本地副本;
4:客户端驱动程序发起的更改
  1. 若要请求更改,客户端驱动程序调用 UsbPm_AssignConnectorPowerLevel。客户端驱动程序可以在使用 UsbPm_Register 注册的EVT_USBPM_EVENT_CALLBACK回调中调用此函数;
  2. 策略管理器将请求转发到 UCM) (USB 连接器管理器。 UcmCx 的客户端驱动程序会执行相应的操作来更改请求的状态;
  3. 使用 ConnectorStateChange 作为事件数据调用客户端驱动程序的EVT_USBPM_EVENT_CALLBACK。 调用还包含连接器句柄;
  4. 客户端驱动程序的完成例程也会被调用,并相应地执行操作;
  5. 在回调中,客户端驱动程序使用给定的连接器句柄调用 UsbPm_RetrieveConnectorState 以获取最新的连接器状态,对其进行检查,并可能决定更新其本地副本;
5:删除中心
  1. 当 UcmCx 设备 (UcmCx 设备上的单个连接器) 被删除时,UCM 会通知策略管理器。 策略管理器从中心集合中删除中心;
  2. 使用 HubRemoval 作为事件数据调用客户端驱动程序的EVT_USBPM_EVENT_CALLBACK实现。 调用还包含中心句柄;
  3. 在客户端驱动程序的 EVT_USBPM_EVENT_CALLBACK 实现中,客户端驱动程序对要删除的中心和连接器执行清理任务。 驱动程序可以调用 UsbPm_RetrieveHubProperties 和 UsbPm_RetrieveConnectorProperties 来获取中心和连接器的属性;
6:客户端注销
  1. 当驱动程序不再需要任何通知时,客户端驱动程序调用 UsbPm_Deregister ;
  2. 策略管理器将客户端句柄注册标记为已取消注册,并且不会调用 EVT_USBPM_EVENT_CALLBACK 回调;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(10)深入理解pandas的核心数据结构:DataFrame高效数据清洗技巧

目录 前言1. DataFrame数据清洗1.1 处理缺失值(NaNs)1.1.1 数据准备1.1.2 读取数据1.1.3 查找具有 null 值或缺失值的行和列1.1.4 计算每列缺失值的总数1.1.5 删除包含 null 值或缺失值的行1.1.6 利用 .fillna() 方法用Portfolio …

Python本地安装whl文件详解与高级pip命令技巧

有些情况我们pip一下包的时候会报错,可能因为延时或许其他不兼容的情况,这时候我们可以通过去网上下载该包的原文件,进行本地物理pip ,在安装网上下载的whl之前,先明白不同后缀的差异;whl下载网址&#xff…

解答word图标变白

把WPS卸载了之后就变成白色了,然后在注册表中把word的地址改成office word的地址之后图标变成这样了,怎么办 1.winR打开命令提示符 2.输入regedit,打开注册表编辑器 3.找到下面这个路径 计算机\HKEY_CLASSES_ROOT\Word.Document.8\Defaul…

【C#】已知有三个坐标点:P0、P1、P2,当满足P3和P4连成的一条直线 与 P0和P1连成一条直线平行且长度一致,该如何计算P3、P4?

问题描述 已知有三个坐标点:P0、P1、P2,当满足P3和P4连成的一条直线 与 P0和P1连成一条直线平行且长度一致,该如何计算P3、P4? 解决办法 思路一:斜率及点斜式方程 # 示例坐标 x0, y0 1, 1 # P0坐标 x1, y1 4, 4 # …

自适应键盘,自带隐藏键盘的输入框(UITextField)

引言 在iOS开发中,输入框占据着举足轻重的地位。与安卓不同,iOS输入框经常面临键盘遮挡的问题,或者无法方便地取消键盘。为了解决这些问题,有许多针对iOS键盘管理的库,如IQKeyboardManager、TPKeyboardAvoiding和Keyb…

分库分表 [ 技术 ] 指南 ✨

目录 ✨探索 技术 分库分表✨ 数据库分库分表指南 一、什么是分库分表 二、分库分表策略 三、分库分表的实现 四、分库分表的常见问题及解决方案 五、总结 相关面试题目 1. 解释什么是数据库分库分表,以及它的主要目的是什么? 2. 描述垂直分库…

STM32学习(1)--STM32介绍

STM32介绍 1.STM32简介2.ARM3.STM32F103C8T64.外设5.命名规则6.系统结构7.引脚定义8.启动配置9.最小系统电路10.新建工程步骤11.工程架构 课程知识及代码来源均来自b站 江协科技,下学期即将做毕设,需要用到STM32单片机,在这个假期我将持续学…

摸鱼大数据——Spark Structured Steaming——新零售数据分析案例

1、数据源介绍 数据内容 字段说明 2、分析需求 数据清洗需求 清洗需求:1) 将客户id(CustomerID)不为0的数据保留下来: CustomerID ! 02) 将商品描述(Description)不为空的数据保留下来: Description !3) 将日期&#…

gds-linkqueue:泛型链式队列

类似于C的queue的泛型容器,初始化、销毁、清空、入队、出队、取队首/尾、队空。 ​​​​​​​ ​​​​​​​

对某次应急响应中webshell的分析

文章前言 在之前处理一起应急事件时发现攻击者在WEB应用目录下上传了webshell,但是webshell似乎使用了某种加密混淆手法,无法直观的看到其中的木马连接密码,而客户非要让我们连接webshell来证实此文件为后门文件且可执行和利用(也是很恼火&a…

fMATLAB中fill函数填充不同区域

只需获取填充区域的边缘信息,函数边缘越详细越好,然后调用fill函数。 fill函数能够根据指定的顶点坐标和填充颜色来绘制多边形或曲线形状,并在其内部填充指定的颜色。这使得在MATLAB中创建具有视觉吸引力的图形变得简单而高效。 fill函数的…

《0基础》学习Python——第二十讲__网路爬虫/<3>

一、用post请求爬取网页 同样与上一节课的get强求的内容差不多,即将requests.get(url,headershead)代码更换成requests.post(url,headershead),其余的即打印获取的内容,如果content-typejson类型的,打印上述代码的请求,则用一个命…

笔记:现代卷积神经网络之VGG

本文为李沐老师《动手学深度学习》笔记小结,用于个人复习并记录学习历程,适用于初学者 神经网络架构设计的模块化 然AlexNet证明深层神经网络卓有成效,但它没有提供一个通用的模板来指导后续的研究人员设计新的网络。 在下面的几个章节中&a…

【Vue】`v-if` 指令详解:条件渲染的高效实现

文章目录 一、v-if 指令概述二、v-if 的基本用法1. 基本用法2. 使用 v-else3. 使用 v-else-if 三、v-if 指令的高级用法1. 与 v-for 一起使用2. v-if 的性能优化 四、v-if 的常见应用场景1. 表单验证2. 弹窗控制 五、v-if 指令的注意事项 Vue.js 是一个用于构建用户界面的渐进式…

Flink调优详解:案例解析(第42天)

系列文章目录 一、Flink-任务参数配置 二、Flink-SQL调优 三、阿里云Flink调优 文章目录 系列文章目录前言一、Flink-任务参数配置1.1 运行时参数1.2 优化器参数1.3 表参数 二、Flink-SQL调优2.1 mini-batch聚合2.2 两阶段聚合2.3 分桶2.4 filter去重(了解&#xf…

【中项】系统集成项目管理工程师-第3章 信息技术服务-3.4服务标准化

前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…

持续集成02--Linux环境更新/安装Java新版本

前言 在持续集成/持续部署(CI/CD)的旅程中,确保开发环境的一致性至关重要。本篇“持续集成02--Linux环境更新/安装Java新版本”将聚焦于如何在Linux环境下高效地更新或安装Java新版本。Java作为广泛应用的编程语言,其版本的更新对…

XLua原理(一)

项目中活动都是用xlua开发的,项目周更热修也是用xlua的hotfix特性来做的。现研究底层原理,对于项目性能有个更好的把控。 本文认为看到该文章的人已具备使用xlua开发的能力,只研究介绍下xlua的底层实现原理。 一.lua和c#交互原理 概括&…

用程序画出三角形图案

创建各类三角形图案 直角三角形&#xff08;左下角&#xff09; #include <iostream> using namespace std;int main() {int rows;cout << "输入行数: ";cin >> rows;for(int i 1; i < rows; i){for(int j 1; j < i; j){cout << &…

003uboot目录分析和两个阶段

我们都知道s3c2440是一个soc&#xff0c;内含cpu和各种控制器、片内的RAM&#xff0c;他的CPU是arm920t。 我们先来分析一下uboot原码的各个目录 1.uboot目录分析 board&#xff1a;board里存放的是支持各个开发板的文件&#xff0c;包括链接脚本 common: common目录中存放的…