组件固件更新 (CFU) INF 文件配置

若要为 CFU 配置自定义 INF 文件,请按照本主题中的指南为固件映像文件和硬件设备提供正确的值和设置。

注意

CFU 在 Windows 10 版本 2004(Windows 10 2020 年 5 月更新)和更高版本中可用。

下面包含的示例 CFU INF 文件提供了设备的自定义 INF 文件的起点。 示例 INF 配置 CFU 收件箱驱动程序 (hidcfu.dll),以启用虚拟 CFU Hid 设备的固件更新方案。 有关示例虚拟设备代码和模拟虚拟在 HID 设备上更新固件的情况的演练的详细信息,请参阅 CFU 虚拟 HID 设备固件更新模拟主题。 以下各部分引用所含的示例 INF 文件,以说明本主题中讨论的配置概念。

必须为设备固件和硬件专门自定义和配置实际的 INF 文件。

开始之前

以下资源将帮助你了解组件固件更新 (CFU) 协议。

概述

若要使用 CFU 模型更新设备的固件映像,应满足以下要求:

  • 为设备提供自定义 INF 文件。 此文件向 CFU 收件箱驱动程序提供信息,用于将固件更新发送到设备。 建议你自定义本主题中下面提供的示例 CFU INF 文件以支持固件更新方案。

  • 你的设备必须附带符合 CFU 协议的固件映像,以便它可以接受来自 CFU 驱动程序的更新。

  • 设备必须将自身作为 HID 设备公开给操作系统(运行 CFU 收件箱驱动程序)并公开 HID 顶级集合 (TLC)。 CFU 收件箱驱动程序在 TLC 上加载,并将固件更新发送到设备。

这样,可以通过 Windows 更新为市面上的设备提供服务。 若要更新组件的固件,请通过 Windows 更新部署固件更新映像。 当 CFU 收件箱驱动程序检测到组件存在时,它会对主机执行必要的操作,并将固件映像传输到设备上的主要组件。

CFU firmware update.

配置自定义 CFU INF 文件

  1. 在自定义 INF 文件中,按此示例所示插入设备的硬件 ID。

    [Standard.NTamd64]
    %CfuVirtualHidDeviceFwUpdate.DeviceDesc%=CfuVirtualHidDeviceFwUpdate, HID\VID_045E&UP:FA00_U:00F5 ; HardwareID for VirtualHidDevice MCU
    

    INF 硬件 ID 设置

    为了使 CFU 收件箱驱动程序与固件通信,INF 中指定的硬件 ID 应与固件的 HID 描述符配置中指定的硬件 ID 匹配。

    如下所示,CfuVirtualHidDeviceFwUpdate.inf 值与虚拟固件模拟驱动程序的 HID 描述符中指定的值匹配。

    [Standard.NTamd64]
    %CfuVirtualHidDeviceFwUpdate.DeviceDesc%=CfuVirtualHidDeviceFwUpdate, HID\VID_045E&UP:FA00_U:00F5
    

    有关详细信息,请参阅 DmfInterface.cg_CfuVirtualHid_HidReportDescriptor(HID 报告描述符)内的以下代码。

    0x06, CFU_DEVICE_USAGE_PAGE,        // USAGE_PAGE(0xFA00)
    0x09, CFU_DEVICE_USAGE,             // USAGE(0xF5)
    
  2. 在自定义 INF 文件中,更新此处显示的以下条目(包括 SourceDisksFilesCopyFiles 部分),以匹配固件更新中的文件。

    例如,虚拟 CFU HID 设备示例支持两个组件(MCU 和音频)。 下面的示例部分指定这些组件的产品/服务和有效负载文件。

    ; Specify the location of the firmware offer
    ; and payload file in the registry.
    ; The files are kept in driver store.
    ; When deployed, %13% would be expanded to
    ; the actual path in driver store.
    ;
    ; You can change subkey name under CFU
    ; (for example, "CfuVirtualHidDevice_MCU"),
    ; and specify your own offer
    ; (for example, "CfuVirtualHidDevice_MCU.offer.bin")
    ; and payload (for example, "CfuVirtualHidDevice_MCU.payload.bin")
    ; file name.
    ;
    HKR,A410A898-8132-4246-AC1A-30F1E98BB0A4\CfuVirtualHidDevice_MCU,Offer,   0x00000000, %13%\CfuVirtualHidDevice_MCU.offer.bin
    HKR,A410A898-8132-4246-AC1A-30F1E98BB0A4\CfuVirtualHidDevice_MCU,Payload, 0x00000000, %13%\CfuVirtualHidDevice_MCU.payload.bin
    HKR,A410A898-8132-4246-AC1A-30F1E98BB0A4\CfuVirtualHidDevice_Audio,Offer,   0x00000000, %13%\CfuVirtualHidDevice_Audio.offer.bin
    HKR,A410A898-8132-4246-AC1A-30F1E98BB0A4\CfuVirtualHidDevice_Audio,Payload, 0x00000000, %13%\CfuVirtualHidDevice_Audio.payload.bin
    
    [SourceDisksFiles]
    CfuVirtualHidDevice_MCU.offer.bin=1
    CfuVirtualHidDevice_MCU.payload.bin=1
    CfuVirtualHidDevice_Audio.offer.bin=1
    CfuVirtualHidDevice_Audio.payload.bin=1
    
    [CfuVirtualHidDeviceFwUpdate.CopyFiles]
    CfuVirtualHidDevice_MCU.offer.bin
    CfuVirtualHidDevice_MCU.payload.bin
    CfuVirtualHidDevice_Audio.offer.bin
    CfuVirtualHidDevice_Audio.payload.bin
    

    有关完整的 CFU INF 示例文件,请参阅下面的示例 CFU INF 文件

    注意

    安装包后,OS 会将 %13% 替换为文件的完整路径,然后再创建注册表值。 因此,驱动程序能够枚举注册表并标识所有固件映像和产品/服务文件。

    注意

    在上面的示例中,“A410A898-8132-4246-AC1A-30F1E98BB0A4”、“产品/服务”、“有效负载”不应更改,因为 CFU 收件箱驱动程序将在运行时查找这些值。

  3. 在自定义 INF 文件中,使用下表和示例 INF 部分中所述的注册表值功能设置指定设备的功能。

    CFU 收件箱驱动程序提供了一种方法来自定义驱动程序行为以针对某些方案进行优化。 这些设置通过注册表设置进行控制,如下面的 CFU 注册表值表中所述。

    例如,根据固件实现,CFU 收件箱驱动程序需要有关值功能使用情况详细信息的信息。 有关详细信息和有关如何执行此操作的示例,请参阅下面的 INF 值功能设置部分。

    可以根据固件实现需求配置其中每个注册表值。

    CFU 注册表值

    注册表值 说明
    对齐 协议属性:此配置所需的 bin 记录对齐方式是什么?

    在协议的有效负载发送阶段,驱动程序会使用有效负载填充许多 Hid 缓冲区,并逐个发送到固件。

    此选项控制打包有效负载时的对齐要求。

    默认使用 8 字节对齐方式。 如果不需要对齐方式,请将此项配置为 1。

    UseHidSetOutputReport 0 - 驱动程序将在发送任何输出报告时使用写入请求。

    1 - 驱动程序将使用 IOCTL_HID_SET_OUTPUT_REPORT 发送任何输出报告。

    默认为 0。 如果基础传输不是 USB(例如基于 BTH 的 HID),则将此项设置为 1。

    OfferInputValueCapabilityUsageRangeMinimum 产品/服务输入报告处理的值功能使用情况最小值。
    OfferOutputValueCapabilityUsageRangeMinimum 产品/服务输出报告处理的值功能使用情况最小值。
    PayloadInputValueCapabilityUsageRangeMinimum 有效负载输入报告处理的值功能使用情况最小值。
    PayloadOutputValueCapabilityUsageRangeMinimum 有效负载输出报告处理的值功能使用情况最小值。
    VersionsFeatureValueCapabilityUsageRangeMinimum 版本功能报告处理的值功能使用情况最小值。

    INF 值功能设置

    为了使 CFU 收件箱驱动程序与固件通信,INF 中指定的值功能使用情况应与固件中 Hid 描述符配置中的使用情况匹配。

    在此示例中,INF 值与虚拟固件模拟驱动程序的 Hid 描述符中指定的值匹配。

    [CfuVirtualHidDeviceFwUpdate_HWAddReg]
    ...
    ...
    HKR,,OfferInputValueCapabilityUsageRangeMinimum,0x00010001,0x1A
    HKR,,OfferOutputValueCapabilityUsageRangeMinimum,0x00010001, 0x1E
    HKR,,PayloadInputValueCapabilityUsageRangeMinimum,0x00010001,0x26
    HKR,,PayloadOutputValueCapabilityUsageRangeMinimum,0x00010001,0x31
    HKR,,VersionsFeatureValueCapabilityUsageRangeMinimum,0x00010001, 0x42
    

    有关详细信息,请参阅 DmfInterface.cg_CfuVirtualHid_HidReportDescriptor(HID 报告描述符)内的以下代码。

    0x85, REPORT_ID_PAYLOAD_INPUT,      // REPORT_ID(34)
    0x75, INPUT_REPORT_LENGTH,          // REPORT SIZE(32)
    0x95, 0x04,                         // REPORT COUNT(4)
    0x19, PAYLOAD_INPUT_USAGE_MIN,      // USAGE MIN (0x26)
    0x29, PAYLOAD_INPUT_USAGE_MAX,      // USAGE MAX (0x29)
    0x81, 0x02,                         // INPUT(0x02)
    
    0x85, REPORT_ID_OFFER_INPUT,        // REPORT_ID(37)
    0x75, INPUT_REPORT_LENGTH,          // REPORT SIZE(32)
    0x95, 0x04,                         // REPORT COUNT(4)
    0x19, OFFER_INPUT_USAGE_MIN,        // USAGE MIN (0x1A)
    0x29, OFFER_INPUT_USAGE_MAX,        // USAGE MAX (0x1D)
    0x81, 0x02,                         // INPUT(0x02)
    
    0x85, REPORT_ID_PAYLOAD_OUTPUT,     // REPORT_ID(32)
    0x75, 0x08,                         // REPORT SIZE(8)
    0x95, OUTPUT_REPORT_LENGTH,         // REPORT COUNT(60)
    0x09, PAYLOAD_OUTPUT_USAGE,         // USAGE(0x31)
    0x92, 0x02, 0x01,                   // OUTPUT(0x02)
    
    0x85, REPORT_ID_OFFER_OUTPUT,       // REPORT_ID(37)
    0x75, INPUT_REPORT_LENGTH,          // REPORT SIZE(32)
    0x95, 0x04,                         // REPORT COUNT(4)
    0x19, OFFER_OUTPUT_USAGE_MIN,       // USAGE MIN (0x1E)
    0x29, OFFER_OUTPUT_USAGE_MAX,       // USAGE MAX (0x21)
    0x91, 0x02,                         // OUTPUT(0x02)
    
    0x85, REPORT_ID_VERSIONS_FEATURE,   // REPORT_ID(32)
    0x75, 0x08,                         // REPORT SIZE(8)
    0x95, FEATURE_REPORT_LENGTH,        // REPORT COUNT(60)
    0x09, VERSIONS_FEATURE_USAGE,       // USAGE(0x42)
    0xB2, 0x02, 0x01,                   // FEATURE(0x02)
    

通过 Windows 更新部署固件包

接下来,通过 Windows 更新部署固件包。

有关部署的信息,请参阅 Windows 10 驱动程序发布工作流(DOCX 下载)

固件更新映像文件格式

固件更新映像有两个部分:产品/服务文件和有效负载文件。 产品/服务包含有关有效负载的必要信息,以允许接收更新的设备中的主要组件,从而确定有效负载是否可接受。 有效负载是主要组件可以使用的地址和字节范围。

产品/服务格式

产品/服务文件是一个 16 字节二进制数据,其结构必须与 CFU 协议规范的第 5.5.1 节中指定的格式匹配。

有效负载格式

有效负载文件是一个二进制文件,其中包含连续存储的记录集合。 每条记录采用以下格式。

Offset 大小 说明
字节 0 DWORD 固件地址 用以写入数据的 Little Endian(LSB 优先)地址。 地址基于 0。 固件可以将此用作偏移量,以在将映像放置在内存中时根据需要确定地址。
字节 4 Byte 长度 有效负载数据的长度。
字节 5-N 字节 数据 有效负载数据的字节数组。

固件更新状态

在协议事务期间,CFU 收件箱驱动程序写入注册表项以指示状态。 下表描述了驱动程序在协议的各个阶段所接触的值的名称、值格式和含义。

  • 表中的 _ID_ 表示从产品/服务文件检索的组件 ID。 如规范中所述,组件 ID 可唯一标识每个组件。

  • 有关值 DWORD 的信息,请参阅规范。

阶段 位置 正则值名称 值 (DWORD)
开始;以前的产品/服务。 {Device Hardware key}\ComponentFirmwareUpdate “ComponentIDCurrentFwVersion” 设备中的版本
{Device Hardware key}\ComponentFirmwareUpdate “ComponentIDFirmwareUpdateStatus” FIRMWARE_UPDATE_STATUS_NOT_STARTED
产品/服务;即将发送产品/服务。 {Device Hardware key}\ComponentFirmwareUpdate “ComponentIDOfferFwVersion” 已发送(或即将发送)到设备的版本。
产品/服务响应(已拒绝) {Device Hardware key}\ComponentFirmwareUpdate “ComponentIDFirmwareUpdateStatusRejectReason” 设备返回的拒绝原因。
产品/服务响应(设备繁忙) {Device Hardware key}\ComponentFirmwareUpdate “ComponentIDFirmwareUpdateStatus” FIRMWARE_UPDATE_STATUS_BUSY_PROCESSING_UPDATE
产品/服务响应(已接受);即将发送有效负载。 {Device Hardware key}\ComponentFirmwareUpdate “ComponentIDFirmwareUpdateStatus” FIRMWARE_UPDATE_STATUS_DOWNLOADING_UPDATE
已接受有效负载。 {Device Hardware key}\ComponentFirmwareUpdate “ComponentIDFirmwareUpdateStatus” FIRMWARE_UPDATE_STATUS_PENDING_RESET
在任何阶段出错。 {Device Hardware key}\ComponentFirmwareUpdate “ComponentIDFirmwareUpdateStatus” FIRMWARE_UPDATE_STATUS_ERROR

示例 CFU INF 文件

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;  Copyright (c) Microsoft Corporation.  All rights reserved.
;
;      THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
;      KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
;      IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
;      PURPOSE.
;
; File:
;
:      CfuVirtualHidDeviceFwUpdate.inx
;
; Description:
;
;      Sample INF file for Cfu virtual Hid device firmware update.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[Version]
Signature="$Windows NT$"
Class=Firmware
ClassGuid={f2e7dd72-6468-4e36-b6f1-6488f42c1b52}
Provider=%ManufacturerName%
CatalogFile=CfuVirtualHidDeviceFwUpdate.cat
DriverVer = 12/16/2019,11.42.16.703
PnPLockDown=1

[SourceDisksNames]
1= %DiskName%

[DestinationDirs]
CfuVirtualHidDeviceFwUpdate.CopyFiles=13

[Manufacturer]
%ManufacturerName%=Standard,NTamd64

[Standard.NTamd64]
%CfuVirtualHidDeviceFwUpdate.DeviceDesc%=CfuVirtualHidDeviceFwUpdate, HID\VID_045E&UP:FA00_U:00F5 ; HardwareID for VirtualHidDevice MCU

[CfuVirtualHidDeviceFwUpdate.NT]
Include            = HidCfu.inf
Needs              = HidCfu.NT
CopyFiles          = CfuVirtualHidDeviceFwUpdate.CopyFiles

[CfuVirtualHidDeviceFwUpdate.NT.Wdf]
Include            = HidCfu.inf
Needs              = HidCfu.NT.Wdf

[CfuVirtualHidDeviceFwUpdate.NT.HW]
AddReg = CfuVirtualHidDeviceFwUpdate_HWAddReg

[CfuVirtualHidDeviceFwUpdate_HWAddReg]
HKR,,FriendlyName,,%FwUpdateFriendlyName%
HKR,,Alignment,0x00010001, 1                       ; (No Alignment)
HKR,,OfferInputValueCapabilityUsageRangeMinimum,0x00010001,0x1A
HKR,,OfferOutputValueCapabilityUsageRangeMinimum,0x00010001, 0x1E
HKR,,PayloadInputValueCapabilityUsageRangeMinimum,0x00010001,0x26
HKR,,PayloadOutputValueCapabilityUsageRangeMinimum,0x00010001,0x31
HKR,,VersionsFeatureValueCapabilityUsageRangeMinimum,0x00010001, 0x42

; Specify the location of the firmware offer and payload file in the registry.
; The files are kept in the driver store.
; When deployed, %13% would be expanded to the actual path
; in driver store.
;
; You can change subkey name under CFU (e.g. "CfuVirtualHidDevice_MCU"), and specify your own offer
; (e.g. "CfuVirtualHidDevice_MCU.offer.bin") and payload (e.g "CfuVirtualHidDevice_MCU.payload.bin") file name.
;
HKR,A410A898-8132-4246-AC1A-30F1E98BB0A4\CfuVirtualHidDevice_MCU,Offer,   0x00000000, %13%\CfuVirtualHidDevice_MCU.offer.bin
HKR,A410A898-8132-4246-AC1A-30F1E98BB0A4\CfuVirtualHidDevice_MCU,Payload, 0x00000000, %13%\CfuVirtualHidDevice_MCU.payload.bin
HKR,A410A898-8132-4246-AC1A-30F1E98BB0A4\CfuVirtualHidDevice_Audio,Offer,   0x00000000, %13%\CfuVirtualHidDevice_Audio.offer.bin
HKR,A410A898-8132-4246-AC1A-30F1E98BB0A4\CfuVirtualHidDevice_Audio,Payload, 0x00000000, %13%\CfuVirtualHidDevice_Audio.payload.bin

[SourceDisksFiles]
CfuVirtualHidDevice_MCU.offer.bin=1
CfuVirtualHidDevice_MCU.payload.bin=1
CfuVirtualHidDevice_Audio.offer.bin=1
CfuVirtualHidDevice_Audio.payload.bin=1

[CfuVirtualHidDeviceFwUpdate.CopyFiles]
CfuVirtualHidDevice_MCU.offer.bin
CfuVirtualHidDevice_MCU.payload.bin
CfuVirtualHidDevice_Audio.offer.bin
CfuVirtualHidDevice_Audio.payload.bin

[CfuVirtualHidDeviceFwUpdate.NT.Services]
Include            = HidCfu.inf
Needs              = HidCfu.NT.Services

; =================== Generic ==================================

[Strings]
ManufacturerName="Surface"
CfuVirtualHidDeviceFwUpdate.DeviceDesc = "CfuVirtualHidDevice Firmware Update"
DiskName = "CfuVirtualHidDevice Firmware Update Installation Disk"
FwUpdateFriendlyName= "CfuVirtualHidDevice Firmware Update"

疑难解答

  1. 检查 Windows 软件跟踪预处理器 (WPP) 日志以查看每个组件的驱动程序端交互。

  2. 检查事件日志是否有任何严重错误。

  3. 检查驱动程序提供的固件更新状态中所述的记帐注册表项。

常见问题解答

我有一个需要更新的组件 A,如何使 CFU 驱动程序能够识别组件 A?

你需要使用组件 A 创建的 TLC 的硬件 ID 配置 CFU 收件箱驱动程序 INF。

我有两个组件:组件 A 和子组件 B。应如何使 CFU 驱动程序能够识别组件 B?

你不需要。 驱动程序不需要知道组件层次结构。 它与主要组件交互。

如何使驱动程序知道需要发送到组件 A 的固件文件(产品/服务、有效负载)文件?

固件文件信息在 INF 中设置为注册表值。

对于主组件 A 及其子组件,我有许多固件文件、多个产品/服务、有效负载。 应如何使驱动程序知道哪个固件文件适用于哪个组件?

固件文件信息在 INF 中设置为注册表值。

我正在使用驱动程序进行固件更新。 如何实现知道更新已成功?

固件更新状态由注册表中的驱动程序作为记帐的一部分进行更新。

其他资源

了解如何使用 Windows Driver Foundation (WDF) 开发 Windows 驱动程序: