CFU V1
本文中CFU(Component Firmware Update)是指基本遵循Microsoft标准升级协议,对image进行升级的技术。
CFU V1支持single bank升级。
CFU V2同时支持single bank和dual bank升级。
备注
V1和V2不兼容。
CFU文件介绍
文件打包
Bank0 APP Image
,Boot Patch Image
,Bank0 System Patch Image
,Bank0 BT Stack Patch Image
和 Bank0 BT Host Image
这五个image是可以被打包升级的。可以单独打包,也可以合并打包进行升级,不过需要确保升级的image size(不包括 Boot Patch Image
)不超过 flash map
配置的OTA Temp区的大小。
通过 MPPackTool.exe
(选择CFU V1) 可以选择需要升级的文件进行CFU打包,会生成 offer bin
(name.offer.bin) 和 payload bin
(name.payload.bin),如下图所示。其中打包Boot Patch Image的时候,需要把 Bank0 Boot Patch Image
和 Bank1 Boot Patch Image
的两个bin文件一起打包。

CFU打包生成的文件
文件格式
Offer Bin
Offer bin提供了images升级的基本信息,比如IC ID,固件版本号等,在传输文件内容前和tool进行信息交互。
Byte |
Field |
Value |
---|---|---|
Byte1 |
Segment number |
0x00 |
Byte2 |
Force ignore version (bit 7) |
0 - 升级的时候固件会检查版本是否允许升级(固件端实现,以实际代码为准) 1 - 升级的时候固件不会检查版本,进行强制升级 |
Force immediate reset (bit6) |
0 - 传输完成升级文件后IC是否重启不做要求 1 - 传输完成升级文件后IC立即重启 |
|
Reserved (bit5-bit2) |
0x00 |
|
Image type (bit1-bit0) |
0 - Bank0 APP Image 1 - Bank0 BT Host Image 2 - Bank0 System Patch Image 3 - other image |
|
Byte3 |
Component ID |
IC的ID 其中87x2G为0x0f |
Byte4 |
Token |
0x00 |
Byte5-Byte8 |
FW Version |
低字节在前,version是4段式的(x.x.x.x),但不是按byte分段的,需要进行特别的解析,在tool中正确的显示,具体可以参考CFU Tool demo code |
Byte9-Byte12 |
Reserved |
0x00 |
Byte13 |
Reserved (bit7-bit6) |
0x00 |
Bank (bit5-bit4) |
0 - bank0 (用于dual bank升级) 1 - bank1 (用于dual bank升级) 2 - single bank (CFU V1只支持单bank升级,因此该字段只能为2) |
|
Protocol version (bit3-bit0) |
0x04 |
|
Byte14-Byte16 |
Reserved |
0x00 |
Payload Bin
Payload bin是将待升级文件的Images,按照Realtek自定义格式重新组包生成的文件,包含了所有image的具体内容。
其组包过程如下:
将待升级文件1的MP image,去掉MP Header,只留真正需要写到flash中的raw data。
将待升级文件1的raw data加上CFU header,CFU header(52 bytes)结构如下。
CFU header data Field
Size(byte)
Value
Image ID
2
0 - Bank0 APP Image
1 - Bank0 BT Host Image
2 - Bank0 System Patch Image
3 - other image
Image Version
4
低字节在前,version是4段式的(x.x.x.x),但不是按byte分段的
End Address
4
先将该image raw data补0,保证size是52的倍数后,再加上CFU header后的总image size
Image Length
4
步骤1得到的image raw data的实际size
Reserved
38
0x00
将待升级文件2-N都按照步骤1和2处理并拼接。
将上述得到的文件内容,每52 byte加上 MSFT header,Payload bin组包 示意图如下。
MSFT header data Field
Size (byte)
Value
Address
4
该MSFT header对应的文件内容的起始地址
Length
1
52
Payload bin组包
举例
文件address 0x00开始加上第一个MSFT header: 0x00 0x00 0x00 0x00 0x34文件address 0x34开始加上第二个MSFT header: 0x34 0x00 0x00 0x00 0x34
CFU流程概述

CFU简要流程图
过滤设备
CFU tool根据 CFUTOOLSettings.ini
中配置的 VID、 PID、UsagePage、UsageTlc、SerialNumber这些信息,过滤出当前符合条件的USB设备,如下所示。
[CFU_VIA_USB_HID]
Vid=0x0bda
Pid=0x4762
UsagePage=0xff0b
UsageTlc=0x0104
...
[DEVICE]
SerialNumber=
提示
VID、PID、SerialNumber都可以在APP层通过宏自行设定,其中,如果
CFUTOOLSettings.ini
的SerialNumber一栏为空,表示不过滤这项信息。UsagePage、UsageTlc可以在cfu interface的report map获取。
传输过程
CFU Firmware Version Request and Response
CFU tool通过get report (report id 0x2A),获取待升级设备的固件信息,具体信息如下。
Byte |
Field |
Value |
---|---|---|
Byte1 |
Component Count |
0x01 |
Byte2-Byte3 |
Reserved |
0x00 |
Byte4 |
Reserved (bit7-bit4) |
0x00 |
Protocol version (bit3-bit0) |
0x04 |
|
Byte5-Byte8 |
FW Version |
低字节在前,version是4段式的(x.x.x.x),但不是按byte分段的,需要进行特别的解析,在tool中正确的显示,具体可以参考CFU Tool demo code |
Byte9 |
Reserved (bit7-bit2) |
0x00 |
Bank (bit1-bit0) |
0x02(表示单bank) |
|
Byte10 |
Component ID |
IC的ID 其中87x2G为0x0f CFU tool目前不做判断 |
Byte11-Byte12 |
Platform ID |
CFU tool目前不做判断 |
Byte13-Byte60 |
Reserved |
0x00 |
CFU Offer Request
CFU tool通过Set report (report id 0x2D),将offer bin的全部内容发送给待升级设备。Offer bin内容参考 Offer Bin。
打包工具生成的offer bin中Force ignore version固定为0,如果本次升级需要进行强制升级,CFU offer request中该字段需要改写为1后进行传输。
CFU Offer Response
待升级设备收到CFU Offer Request以后,需要对收到的offer request内容进行判断,并通过USB IN transfer将带判断结果的response发送给CFU tool (report id 0x2D)。其中Component ID必须进行判断;当Force ignore version为0时,可以对FW version进行判断;Protocol version和Bank可以根据需要选择是否要进行判断(默认没有判断)。
Byte |
Field |
Value |
---|---|---|
Byte1-Byte3 |
Reserved |
0x00 |
Byte4 |
Token |
0x00 |
Byte5-Byte8 |
Reserved |
0x00 |
Byte9 |
当offer status为 FIRMWARE_UPDATE_OFFER_REJECT (0x02) 时有效 |
|
Byte10-Byte12 |
Reserved |
0x00 |
Byte13 |
FIRMWARE_UPDATE_OFFER_ACCEPT (0x01):表示可以进行固件升级 其他值:表示发生error,CFU tool会停止升级 |
|
Byte14-Byte16 |
Reserved |
0x00 |
Offer status code |
Name |
Cause |
---|---|---|
0x00 |
FIRMWARE_UPDATE_OFFER_SKIP |
The Offer needs to be skipped at this time, indicating to the CFU driver or tool to please offer again during next cycle through the Offer List. |
0x01 |
FIRMWARE_UPDATE_OFFER_ACCEPT |
Once FIRMWARE_UPDATE_FLAG_LAST_BLOCK has been issued, the Primary Component can then determine if the payload is appropriate. If so, it is returned. |
0x02 |
FIRMWARE_UPDATE_OFFER_REJECT |
Once FIRMWARE_UPDATE_FLAG_LAST_BLOCK has been issued, the Primary Component can then determine if the payload is appropriate. If not, this will be returned. |
0x03 |
FIRMWARE_UPDATE_OFFER_BUSY |
The offer needs to be delayed at this time. The CFU driver or tool should not proceed to another Offer in the Offer List. The driver or tool may subsequently abandon the update, wait and retry the same Offer, issue OFFER_NOTIFY_ON_READY or issue OFFER_INFO_START_ENTIRE_TRANSACTION to restart the entire Offer process. |
0x04 |
FIRMWARE_UPDATE_OFFER_COMMAND_READY |
Issued after receipt of OFFER_NOTIFY_ON_READY request when the Primary Component is ready to accept Offers. |
0xff |
FIRMWARE_UPDATE_CMD_NOT_SUPPORTED |
General error in interpreting the Offer. |
Reject reason code |
Name |
Cause |
---|---|---|
0x00 |
FIRMWARE_OFFER_REJECT_OLD_FW |
The offer was rejected because the Major and Minor Version is not newer than the current image. |
0x01 |
FIRMWARE_OFFER_REJECT_INV_COMPONENT |
The offer was rejected due to a mismatch of Component ID. |
0x02 |
FIRMWARE_UPDATE_OFFER_SWAP_PENDING |
The offer was rejected because a previous update has been downloaded but not yet applied. |
0x03 |
FIRMWARE_OFFER_REJECT_MISMATCH |
The offer was rejected due to a mismatch of Build Type or Signer required. |
0x04 |
FIRMWARE_OFFER_REJECT_BANK |
The Bank being offered for the Component is currently in use and cannot be updated. |
0x05 |
FIRMWARE_OFFER_REJECT_PLATFORM |
The offer was rejected due to a mismatch of Platform ID. |
0x06 |
FIRMWARE_OFFER_REJECT_MILESTONE |
The offer was rejected due to a mismatch of Milestone. |
0x07 |
FIRMWARE_OFFER_REJECT_INV_PCOL_REV |
The offer indicates an interface CFU or SFUA Protocol Revision that the receiving product does not support. |
0x08 |
FIRMWARE_OFFER_REJECT_VARIANT |
The offer was rejected because the Variant bit of the Variants Mask applicable to this hardware is 0. |
CFU Data Request
CFU tool通过Set report (report id 0x2A),将payload bin中的升级文件内容(除了MSFT Header外的全部内容)发送给待升级设备。待升级设备收到数据并检查通过后,将数据存储到OTA Temp区。
Byte |
Field |
Value |
---|---|---|
Byte1 |
Flags |
0x80 - 整个CFU传输的第一笔数据 0x40 - 整个CFU传输的最后一笔数据 0x00/0x08 - 中间的数据 |
Byte2 |
Length |
52 |
Byte3-Byte4 |
Sequence Number |
从0开始每笔加1 |
Byte5-Byte8 |
Target Address |
该笔数据对应的 MSFT header 的address |
Byte9-Byte60 |
CFU data |
payload bin data(去掉MSFT Header) |
CFU Data Response
待升级设备收到CFU Data Request以后,通过USB IN transfer将response发送给CFU tool (report id 0x2C)。
Byte |
Field |
Value |
---|---|---|
Byte1-Byte2 |
Sequence Number |
与对应的CFU Data Request中的Sequence Number值相同 |
Byte3-Byte4 |
Reserved |
0x00 |
Byte5 |
FIRMWARE_UPDATE_SUCCESS(0x00):表示该笔数据被正确接收、处理和写入flash 其他值:表示发生error,CFU tool会停止升级 |
|
Byte6-Byte16 |
Reserved |
0x00 |
Status Code |
Name |
Description |
---|---|---|
0x00 |
FIRMWARE_UPDATE_SUCCESS |
No Error, the requested function(s) succeeded. |
0x01 |
FIRMWARE_UPDATE_ERROR_PREPARE |
Could not either:
Copy the configuration data to the upper block. |
0x02 |
FIRMWARE_UPDATE_ERROR_WRITE |
Could not write the bytes. |
0x03 |
FIRMWARE_UPDATE_ERROR_COMPLETE |
Could not set up the invocation of the new image, in response to FIRMWARE_UPDATE_FLAG_LAST_BLOCK. |
0x04 |
FIRMWARE_UPDATE_ERROR_VERIFY |
Verification of the CFU data failed, in response to FIRMWARE_UPDATE_FLAG_VERIFY. |
0x05 |
FIRMWARE_UPDATE_ERROR_CRC |
CRC of the image failed, in response to FIRMWARE_UPDATE_FLAG_LAST_BLOCK. |
0x06 |
FIRMWARE_UPDATE_ERROR_SIGNATURE |
Signature verification failed, in response to FIRMWARE_UPDATE_FLAG_LAST_BLOCK. |
0x07 |
FIRMWARE_UPDATE_ERROR_VERSION |
Version verification failed, in response to FIRMWARE_UPDATE_FLAG_LAST_BLOCK. |
0x08 |
FIRMWARE_UPDATE_SWAP_PENDING |
CFU image has already been updated and invocation is pending. No further CFU Offers or CFU Data can be accepted until the invocation has completed. |
0x09 |
FIRMWARE_UPDATE_ERROR_INVALID_ADDR |
Target address is invalid. |
0x0a |
FIRMWARE_UPDATE_ERROR_NO_OFFER |
The CFU Data Report was received without prior acceptance of a CFU Offer. |
0x0b |
FIRMWARE_UPDATE_ERROR_INVALID |
General error for unspecified invalid input, such as an invalid Data Length or implementation-specific violations. |
升级成功或失败
在传输过程中,CFU tool可能会收到以下error response的情况:
当CFU tool收到offer response中的Offer status不是FIRMWARE_UPDATE_OFFER_ACCEPT (0x01)。
当CFU tool收到data response中的Status Code不是FIRMWARE_UPDATE_SUCCESS (0x00)。
当CFU tool收到error response后,默认处理是认为本次升级失败,立即停止升级。
当CFU tool传输完最后一笔data request(Flags为0x40)后,待升级设备对升级文件进行完整性校验通过后,回复success response给CFU tool,认为本次升级成功。之后,升级设备会自行重启,并搬运OTA Temp中存储的升级文件到flash运行区域。待升级设备重启后,CFU tool可以通过CFU Firmware Version Request获取版本号以确认是否真的升级成功,如下图所示。

CFU成功流程图
提示
针对error response的处理,V2.1.1.0以及之前版本的CFU tool默认做法与最新版本有所区别,只有在收到FIRMWARE_UPDATE_ERROR_WRITE时会立即停止升级,其他error会进行retry,依旧收到error response,才会认为本次升级失败。如果用户想修改tool的这部分行为,可以参考CFU Tool demo code。
CFU HID描述符
#define REPORT_ID_CFU_FEATURE 0x2A
#define REPORT_ID_CFU_FEATURE_EX 0x2B
#define REPORT_ID_CFU_OFFER_INPUT 0x2D
#define REPORT_ID_CFU_OFFER_OUTPUT REPORT_ID_CFU_OFFER_INPUT
#define REPORT_ID_CFU_PAYLOAD_INPUT 0x2C
#define REPORT_ID_CFU_PAYLOAD_OUTPUT REPORT_ID_CFU_FEATURE
#define USAGE_ID_CFU_PAYLOAD_OUTPUT 0x61
#define USAGE_ID_CFU_FEATURE 0x62
#define USAGE_ID_CFU_FEATURE_EX 0x65
#define USAGE_ID_CFU_PAYLOAD_INPUT_MIN 0x66
#define USAGE_ID_CFU_PAYLOAD_INPUT_MAX 0x69
#define USAGE_ID_CFU_OFFER_INPUT_MIN 0x8A
#define USAGE_ID_CFU_OFFER_INPUT_MAX 0x8D
#define USAGE_ID_CFU_OFFER_OUTPUT_MIN 0x8E
#define USAGE_ID_CFU_OFFER_OUTPUT_MAX 0x91
0x06, 0x0B, 0xFF, // Usage Page (Vendor Defined 0xFF0B)
0x0A, 0x04, 0x01, // Usage (0x0104)
0xA1, 0x01, // Collection (Application)
// 8-bit data
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x3c, // Report Count (60)
0x85, REPORT_ID_CFU_FEATURE, // Report ID (0x2A)
0x09, 0x60, // Usage (0x60)
0x82, 0x02, 0x01, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Buffered Bytes)
0x09, USAGE_ID_CFU_PAYLOAD_OUTPUT, // Usage (0x61)
0x92, 0x02, 0x01, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x09, USAGE_ID_CFU_FEATURE, // Usage (0x62)
0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x85, REPORT_ID_CFU_FEATURE_EX, // Report ID (0x2B)
0x09, USAGE_ID_CFU_FEATURE_EX, // Usage (0x65)
0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
// 32-bit data
0x17, 0x00, 0x00, 0x00, 0x80, // Logical Minimum (-2147483649)
0x27, 0xFF, 0xFF, 0xFF, 0x7F, // Logical Maximum (2147483646)
0x75, 0x20, // Report Size (32)
0x95, 0x04, // Report Count (4)
0x85, REPORT_ID_CFU_PAYLOAD_INPUT, // Report ID (0x2C)
0x19, USAGE_ID_CFU_PAYLOAD_INPUT_MIN,// Usage Minimum (0x66)
0x29, USAGE_ID_CFU_PAYLOAD_INPUT_MAX,// Usage Maximum (0x69)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, REPORT_ID_CFU_OFFER_INPUT, // Report ID (0x2D)
0x19, USAGE_ID_CFU_OFFER_INPUT_MIN, // Usage Minimum (0x8A)
0x29, USAGE_ID_CFU_OFFER_INPUT_MAX, // Usage Maximum (0x8D)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, USAGE_ID_CFU_OFFER_OUTPUT_MIN,// Usage Minimum (0x8E)
0x29, USAGE_ID_CFU_OFFER_OUTPUT_MAX,// Usage Maximum (0x91)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection