eFuse 管理器

[English]

简介

eFuse 是一种微型的一次性可编程保险丝,可以通过“烧录”(即编程)将数据存储到 ESP32-C5 中。eFuse 位组成不同的数据字段,用于系统参数(即 ESP32-C5 的 ESP-IDF 使用的数据参数)或用户自定义参数。

eFuse 管理器组件中集合了多种工具和 API,可帮助定义、烧录和访问 eFuse 参数。常用的工具和 API 包括:

  • 表格格式,用于在 CSV 文件中定义 eFuse 数据字段

  • efuse_table_gen.py 工具,用于生成 CSV 文件指定的 eFuse 数据字段对应的 C 结构体

  • 用于读/写 eFuse 数据字段的 C API 集合

eFuse Manager 与 idf.py

idf.py 通过 idf.py efuse-<subcommand> 命令为 eFuse 管理器提供了部分功能。本文档主要使用基于 idf.py 的命令,只有在涉及高级功能或罕见情况时,会使用基于 espefuse 的命令。要查看所有可用的命令,请运行 idf.py --help 并搜索以 efuse- 为前缀的命令。

硬件描述

ESP32-C5 有多个 eFuse,可用于存储系统参数和用户参数。每个 eFuse 都是一个一位字段,可以烧写为 1,之后就不能再恢复为 0。eFuse 位被分成了多个 256 位的块,每个块又被分成 8 个 32 位寄存器。部分块保留用于系统参数,其它块可用于用户参数。

如需了解更多内容,请参阅 ESP32-C5 技术参考手册 > eFuse 控制器 (eFuse) [PDF]。

ESP32-C5 有 11 个 eFuse 块,每个块的大小为 256 位(并非所有位都可用于用户参数):

  • EFUSE_BLK0 完全用于系统参数;

  • EFUSE_BLK1 完全用于系统参数;

  • EFUSE_BLK2 完全用于系统参数;

  • EFUSE_BLK3(也称为 EFUSE_BLK_USER_DATA)可用于用户参数;

  • EFUSE_BLK4 至 EFUSE_BLK8(即 EFUSE_BLK_KEY0 至 EFUSE_BLK_KEY4)可以存储安全启动或 flash 加密的密钥。不使用这两个功能时,可以用于用户参数。

  • EFUSE_BLK9(即 EFUSE_BLK_KEY5)可用于存储安全启动或 flash 加密的密钥。不使用这两个功能时,可用于用户参数。

  • EFUSE_BLK10(即 EFUSE_BLK_SYS_DATA_PART2)保留用于系统参数。

定义 eFuse 字段

eFuse 字段通过 CSV 文件中特定格式的表格进行定义。通过这种格式,可定义任意长度和任意位数的 eFuse 字段。

另外,通过这种格式,可以结构化地定义由子字段组成的 eFuse 字段,这意味着一个父 eFuse 字段可能由占用相同 eFuse 位的多个子 eFuse 字段组成。

定义格式

一般情况下,每个记录在定义表格中占据一行,每行包含以下值(也就是列):

# field_name, efuse_block(EFUSE_BLK0..EFUSE_BLK10), bit_start(0..255), bit_count(1..256), comment
  • field_name

    • eFuse 字段的名称。

    • 字段名称前会自动添加 ESP_EFUSE_ 前缀,在 C 代码中,可通过此名称来访问 eFuse 字段。

    • 对于每个 eFuse 字段,field_name 必须唯一。

    • 如果此值为空,说明该行与前一行合并。这样就可以定义任意位排序的 eFuse 字段(例如通用表中的 MAC_FACTORY 字段)。

    • 使用 . 来定义一个子 eFuse 字段。详情请参考 结构化 eFuse 字段

  • efuse_block

    • eFuse 字段的块号。例如 EFUSE_BLK0 到 EFUSE_BLK10。

    • 这一字段决定了 eFuse 字段在哪个块中。

  • bit_start

    • eFuse 字段在块内的位置偏移(0 至 255 位)。

    • bit_start 是可选项,可省略。

      • 当省略时,如果上一条记录位于同一个 eFuse 块中,bit_start 会被设置为上一条记录的 bit_start + bit_count

      • 如果上一条记录位于不同的 eFuse 块中,则会报错。

  • bit_count

    • eFuse 字段的大小,以位为单位(1 至 N)。

    • bit_count 不能省略

    • 如将其设置为 MAX_BLK_LEN,则此 eFuse 字段为块中允许的最大 eFuse 字段大小。

  • comment

    • 描述 eFuse 字段的注释。

    • 此注释会逐字复制到 C 头文件中。

如果一个 eFuse 字段需要非顺序位序,那么该 eFuse 字段将占用多行。应在第一行的 field_name 处定该 eFuse 字段的名称,并且将其他行的 field_name 留空。这样就表明这些行属于同一个 eFuse 字段。

以下示例中定义了两个 eFuse 字段。首先定义非连续的 eFuse 字段 MAC_FACTORY,然后定义了常规 eFuse 字段 MAC_FACTORY_CRC

# Factory MAC address #
#######################
MAC_FACTORY,            EFUSE_BLK0,    72,    8,    Factory MAC addr [0]
,                       EFUSE_BLK0,    64,    8,    Factory MAC addr [1]
,                       EFUSE_BLK0,    56,    8,    Factory MAC addr [2]
,                       EFUSE_BLK0,    48,    8,    Factory MAC addr [3]
,                       EFUSE_BLK0,    40,    8,    Factory MAC addr [4]
,                       EFUSE_BLK0,    32,    8,    Factory MAC addr [5]
MAC_FACTORY_CRC,        EFUSE_BLK0,    80,    8,    CRC8 for factory MAC address

在 C 代码中,可以通过 ESP_EFUSE_MAC_FACTORYESP_EFUSE_MAC_FACTORY_CRC 使用这两个字段。

结构化 eFuse 字段

通常情况下,一个 eFuse 字段代表一个特定的参数。不过,在某些情况下,一个 eFuse 字段可能由多个子字段组成,因此有必要隔离访问这些子字段。例如,如果一个 eFuse 字段包含一个浮点参数,则可以将浮点的符号、指数和尾数字段作为单独的 eFuse 字段进行访问。

因此,可以在 field_name 中使用 . 操作符,以结构化的方式定义 eFuse 字段。例如,XX.YY.ZZ 定义了一个 eFuse 字段 ZZ,它是 eFuse 字段 YY 的子字段,而 YY 又是 eFuse 字段 XX 的子字段。

以下示例展示了如何以定义结构化 eFuse 字段:

WR_DIS,                           EFUSE_BLK0,   0,    32,     Write protection
WR_DIS.RD_DIS,                    EFUSE_BLK0,   0,    1,      Write protection for RD_DIS
WR_DIS.FIELD_1,                   EFUSE_BLK0,   1,    1,      Write protection for FIELD_1
WR_DIS.FIELD_2,                   EFUSE_BLK0,   2,    4,      Write protection for FIELD_2 (includes B1 and B2)
WR_DIS.FIELD_2.B1,                EFUSE_BLK0,   2,    2,      Write protection for FIELD_2.B1
WR_DIS.FIELD_2.B2,                EFUSE_BLK0,   4,    2,      Write protection for FIELD_2.B2
WR_DIS.FIELD_3,                   EFUSE_BLK0,   5,    1,      Write protection for FIELD_3
WR_DIS.FIELD_3.ALIAS,             EFUSE_BLK0,   5,    1,      Write protection for FIELD_3 (just a alias for WR_DIS.FIELD_3)
WR_DIS.FIELD_4,                   EFUSE_BLK0,   7,    1,      Write protection for FIELD_4

在上例中可以看出:

  • WR_DIS 为父 eFuse 字段。其他所有行的 field_name 都具有 WR_DIS. 前缀,因此都是 WR_DIS 的子字段。

  • 子字段必须与父字段使用相同的位。注意子字段和父字段的 bit_startbit_count

    • 子字段的位总是在其父字段范围内。例如,WR_DIS.RD_DISWR_DIS.RD_DIS 占用了 WR_DIS 的第一位和第二位。

    • 子字段使用的位不能重叠(子字段有别名时除外)。

  • 可以将别名创建为子字段。例如,WR_DIS.FIELD_3.ALIAS 既是 WR_DIS.FIELD_3 的子字段,又是别名,因为它们占用的位相同。

所有 eFuse 字段最终都会通过 efuse_table_gen.py 工具转换为 C 结构体。每个 C 结构体从 eFuse 字段的 field_name 中衍生出标识符,并用 _ 替换所有的 . 符号。以 WR_DIS.RD_DISWR_DIS.FIELD_2.B1 为例,这两个 eFuse 字段用 C 语言分别表示为 ESP_EFUSE_WR_DIS_RD_DISESP_EFUSE_WR_DIS_FIELD_2_B1

efuse_table_gen.py 工具还会检查字段是否相互重叠并在字段范围内。如有违反,会生成以下错误:

Field at USER_DATA, EFUSE_BLK3, 0, 256 intersected with SERIAL_NUMBER, EFUSE_BLK3, 0, 32

要解决此问题,可使用 USER_DATA.SERIAL_NUMBER,让 SERIAL_NUMBER 成为 USER_DATA 的子字段。

Field at FIELD, EFUSE_BLK3, 0, 50 out of range  FIELD.MAJOR_NUMBER, EFUSE_BLK3, 60, 32

要解决此问题,可将 FIELD.MAJOR_NUMBERbit_start60 改为 0,使 MAJOR_NUMBERFIELD 重叠。

efuse_table_gen.py 工具

efuse_table_gen.py 工具能够从 CSV 文件生成 C 源文件,其中包含 CSV 文件中定义的 eFuse 字段的对应 C 结构体(类型为 esp_efuse_desc_t)。此外,该工具还会在生成 C 源文件前对 CSV 文件进行检查,以确保:

  • eFuse 字段的名称唯一

  • eFuse 字段使用的位不重叠

如前所述,eFuse 字段可用于存储系统参数或用户参数。由于系统参数 eFuse 字段是 ESP-IDF 和 ESP32-C5 的内在要求,这些 eFuse 字段被定义在 通用 CSV 文件中,即 esp_efuse_table.csv 中,是 ESP-IDF 的一部分。对于用户参数 eFuse 字段,用户应在 自定义 CSV 文件(如 esp_efuse_custom_table.csv)中进行定义。

要从 通用 CSV 文件生成 C 源文件,运行 idf.py efuse-common-table 或以下命令:

cd $IDF_PATH/components/efuse/
./efuse_table_gen.py --idf_target esp32c5 esp32c5/esp_efuse_table.csv

然后,就会在路径 $IDF_PATH/components/efuse/esp32c5 中生成以下 C 源文件/头文件:

  • esp_efuse_table.c 文件,包含系统参数 eFuse 字段的 C 结构体。

  • esp_efuse_table.h 文件,位于 include 文件夹。应用程序可包含该头文件,以使用上述 C 结构体。

要使用 自定义 CSV 文件生成 C 源文件,请运行 idf.py efuse-custom-table 或以下命令:

cd $IDF_PATH/components/efuse/
./efuse_table_gen.py --idf_target esp32c5 esp32c5/esp_efuse_table.csv PROJECT_PATH/main/esp_efuse_custom_table.csv

然后在 PROJECT_PATH/main 路径下生成 C 源/头文件:

  • esp_efuse_custom_table.c 文件,包含用户参数 eFuse 字段的 C 结构体。

  • esp_efuse_custom_table.h 文件,位于 include 文件夹。应用程序可包含该头文件,以使用上述 C 结构体。

要使用生成的字段,需添加以下头文件:

#include "esp_efuse.h"
#include "esp_efuse_table.h" // 或 "esp_efuse_custom_table.h"

支持的编码方式

eFuse 支持各种编码方式,能够检测或纠正错误,保护 eFuse 数据不受损坏。

ESP32-C5 不支持选择编码方式,会自动将以下编码方案应用于各 eFuse 块:

  • 非编码 方式,应用于 EFUSE_BLK0。

  • RS 编码 方式。应用于 EFUSE_BLK1 - EFUSE_BLK10。

非编码 方式

非编码 方式会自动应用于 EFUSE_BLK0。此方式不涉及任何编码,只是在硬件中维护 EFUSE_BLK0 的四个备份,因此,每个位实际存储四次,EFUSE_BLK0 也可以多次写入。

该方案由硬件自动应用,软件中不可见。

RS 编码 方式

  • RS 编码 方式,即 Reed-Solomon 编码方式,会自动应用于 EFUSE_BLK1 至 EFUSE_BLK10。该编码方式支持至多 6 个字节的自动纠错。

软件使用 RS(44, 32) 对 32 字节的 EFUSE_BLKx 进行编码,生成一个 12 字节的校验码,然后将 EFUSE_BLKx 和校验码同时烧录到 eFuse 中。

在回读 eFuse 块时,eFuse 控制器会对 RS 编码 进行自动解码和纠错。因为 RS 校验码是根据整个 256 位 eFuse 块生成的,所以每个块只能写入一次,且必须采用批量写入模式。

批量写入模式

如需在运行时写入 eFuse 字段,可能要采用批量写入模式,具体取决于 eFuse 块使用的编码方案。批量写入模式的使用步骤如下:

  1. 调用 esp_efuse_batch_write_begin() 启用批量写入模式。

  2. 使用各 esp_efuse_write_... 函数,按照常规方法写入 eFuse 字段。

  3. 完成所有写入后,调用 esp_efuse_batch_write_commit() 将准备好的数据烧录到 eFuse 块中。

警告

如果 eFuse 块中已经存在通过 Reed-Solomon 编码方案预先写入的数据,则无法在不破坏先前数据校验和/校验符号的情况下,写入额外的内容(即使需要写入的位为空)。

先前的校验和/校验符号会被新的校验和/校验符号覆盖,并完全销毁。(但不会损坏有效负载 eFuse)。

如发现在 CUSTOM_MAC、SPI_PAD_CONFIG_HD、SPI_PAD_CONFIG_CS 等块中存在预写入数据,请联系乐鑫获取所需的预烧录 eFuse。

仅供测试(不推荐):可以忽略或抑制违反编码方式数据的错误,从而在 eFuse 块中烧录必要的位。

eFuse API

可以通过指向描述结构的指针来访问 eFuse 字段。API 函数可以实现一些基本操作:

经常使用的字段有专门的函数可供使用,例如 esp_efuse_get_pkg_ver()

eFuse 密钥 API

EFUSE_BLK_KEY0 - EFUSE_BLK_KEY5 可以保存 6 个长度为 256 位的密钥。每个密钥都有一个 ESP_EFUSE_KEY_PURPOSE_x 字段说明密钥用途。用途字段描述见 esp_efuse_purpose_t

类似 ESP_EFUSE_KEY_PURPOSE_XTS_AES_... 的用途用于 flash 加密。

类似 ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST... 的用途用于安全启动。

一些 eFuse API 可用于处理密钥状态:

如何添加新字段

  1. 为新字段查找空闲位。运行 idf.py show-efuse-table 查看 esp_efuse_table.csv 文件,或运行以下命令:

$ ./efuse_table_gen.py esp32c5/esp_efuse_table.csv --info

Verifying efuse table...
Max number of bits in BLK 256
Sorted efuse table:
#       field_name                      efuse_block     bit_start       bit_count
1       WR_DIS                          EFUSE_BLK0         0               32
2       WR_DIS.RD_DIS                   EFUSE_BLK0         0               1
3       WR_DIS.DIS_ICACHE               EFUSE_BLK0         2               1
4       WR_DIS.DIS_USB_JTAG             EFUSE_BLK0         2               1
5       WR_DIS.DIS_FORCE_DOWNLOAD       EFUSE_BLK0         2               1
6       WR_DIS.DIS_TWAI                 EFUSE_BLK0         2               1
7       WR_DIS.JTAG_SEL_ENABLE          EFUSE_BLK0         2               1
8       WR_DIS.DIS_PAD_JTAG             EFUSE_BLK0         2               1
9       WR_DIS.DIS_DOWNLOAD_MANUAL_ENCRYPT      EFUSE_BLK0         2               1
10      WR_DIS.WDT_DELAY_SEL            EFUSE_BLK0         3               1
11      WR_DIS.SPI_BOOT_CRYPT_CNT       EFUSE_BLK0         4               1
12      WR_DIS.SECURE_BOOT_KEY_REVOKE0  EFUSE_BLK0         5               1
13      WR_DIS.SECURE_BOOT_KEY_REVOKE1  EFUSE_BLK0         6               1
14      WR_DIS.SECURE_BOOT_KEY_REVOKE2  EFUSE_BLK0         7               1
15      WR_DIS.KEY_PURPOSE_0            EFUSE_BLK0         8               1
16      WR_DIS.KEY_PURPOSE_1            EFUSE_BLK0         9               1
17      WR_DIS.KEY_PURPOSE_2            EFUSE_BLK0         10              1
18      WR_DIS.KEY_PURPOSE_3            EFUSE_BLK0         11              1
19      WR_DIS.KEY_PURPOSE_4            EFUSE_BLK0         12              1
20      WR_DIS.KEY_PURPOSE_5            EFUSE_BLK0         13              1
21      WR_DIS.SEC_DPA_LEVEL            EFUSE_BLK0         14              1
22      WR_DIS.SECURE_BOOT_EN           EFUSE_BLK0         15              1
23      WR_DIS.SECURE_BOOT_AGGRESSIVE_REVOKE    EFUSE_BLK0         16              1
24      WR_DIS.SPI_DOWNLOAD_MSPI_DIS    EFUSE_BLK0         17              1
25      WR_DIS.FLASH_TPUW               EFUSE_BLK0         18              1
26      WR_DIS.DIS_DOWNLOAD_MODE        EFUSE_BLK0         18              1
27      WR_DIS.DIS_DIRECT_BOOT          EFUSE_BLK0         18              1
28      WR_DIS.DIS_USB_SERIAL_JTAG_ROM_PRINT    EFUSE_BLK0         18              1
29      WR_DIS.DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE        EFUSE_BLK0         18              1
30      WR_DIS.ENABLE_SECURITY_DOWNLOAD         EFUSE_BLK0         18              1
31      WR_DIS.UART_PRINT_CONTROL       EFUSE_BLK0         18              1
32      WR_DIS.FORCE_SEND_RESUME        EFUSE_BLK0         18              1
33      WR_DIS.SECURE_VERSION           EFUSE_BLK0         18              1
34      WR_DIS.SECURE_BOOT_DISABLE_FAST_WAKE    EFUSE_BLK0         19              1
35      WR_DIS.BLK1                     EFUSE_BLK0         20              1
36      WR_DIS.MAC                      EFUSE_BLK0         20              1
37      WR_DIS.MAC_EXT                  EFUSE_BLK0         20              1
38      WR_DIS.SYS_DATA_PART1           EFUSE_BLK0         21              1
39      WR_DIS.BLOCK_SYS_DATA1          EFUSE_BLK0         21              1
40      WR_DIS.BLOCK_USR_DATA           EFUSE_BLK0         22              1
41      WR_DIS.CUSTOM_MAC               EFUSE_BLK0         22              1
42      WR_DIS.BLOCK_KEY0               EFUSE_BLK0         23              1
43      WR_DIS.BLOCK_KEY1               EFUSE_BLK0         24              1
44      WR_DIS.BLOCK_KEY2               EFUSE_BLK0         25              1
45      WR_DIS.BLOCK_KEY3               EFUSE_BLK0         26              1
46      WR_DIS.BLOCK_KEY4               EFUSE_BLK0         27              1
47      WR_DIS.BLOCK_KEY5               EFUSE_BLK0         28              1
48      WR_DIS.BLOCK_SYS_DATA2          EFUSE_BLK0         29              1
49      WR_DIS.USB_EXCHG_PINS           EFUSE_BLK0         30              1
50      WR_DIS.VDD_SPI_AS_GPIO          EFUSE_BLK0         30              1
51      WR_DIS.SOFT_DIS_JTAG            EFUSE_BLK0         31              1
52      RD_DIS                          EFUSE_BLK0         32              7
53      RD_DIS.BLOCK_KEY0               EFUSE_BLK0         32              1
54      RD_DIS.BLOCK_KEY1               EFUSE_BLK0         33              1
55      RD_DIS.BLOCK_KEY2               EFUSE_BLK0         34              1
56      RD_DIS.BLOCK_KEY3               EFUSE_BLK0         35              1
57      RD_DIS.BLOCK_KEY4               EFUSE_BLK0         36              1
58      RD_DIS.BLOCK_KEY5               EFUSE_BLK0         37              1
59      RD_DIS.BLOCK_SYS_DATA2          EFUSE_BLK0         38              1
60      DIS_ICACHE                      EFUSE_BLK0         40              1
61      DIS_USB_JTAG                    EFUSE_BLK0         41              1
62      DIS_FORCE_DOWNLOAD              EFUSE_BLK0         44              1
63      SPI_DOWNLOAD_MSPI_DIS           EFUSE_BLK0         45              1
64      DIS_TWAI                        EFUSE_BLK0         46              1
65      JTAG_SEL_ENABLE                 EFUSE_BLK0         47              1
66      SOFT_DIS_JTAG                   EFUSE_BLK0         48              3
67      DIS_PAD_JTAG                    EFUSE_BLK0         51              1
68      DIS_DOWNLOAD_MANUAL_ENCRYPT     EFUSE_BLK0         52              1
69      USB_EXCHG_PINS                  EFUSE_BLK0         57              1
70      VDD_SPI_AS_GPIO                 EFUSE_BLK0         58              1
71      KM_DISABLE_DEPLOY_MODE          EFUSE_BLK0         64              4
72      KM_RND_SWITCH_CYCLE             EFUSE_BLK0         68              2
73      KM_DEPLOY_ONLY_ONCE             EFUSE_BLK0         70              4
74      FORCE_USE_KEY_MANAGER_KEY       EFUSE_BLK0         74              4
75      FORCE_DISABLE_SW_INIT_KEY       EFUSE_BLK0         78              1
76      WDT_DELAY_SEL                   EFUSE_BLK0         80              2
77      SPI_BOOT_CRYPT_CNT              EFUSE_BLK0         82              3
78      SECURE_BOOT_KEY_REVOKE0         EFUSE_BLK0         85              1
79      SECURE_BOOT_KEY_REVOKE1         EFUSE_BLK0         86              1
80      SECURE_BOOT_KEY_REVOKE2         EFUSE_BLK0         87              1
81      KEY_PURPOSE_0                   EFUSE_BLK0         88              4
82      KEY_PURPOSE_1                   EFUSE_BLK0         92              4
83      KEY_PURPOSE_2                   EFUSE_BLK0         96              4
84      KEY_PURPOSE_3                   EFUSE_BLK0        100              4
85      KEY_PURPOSE_4                   EFUSE_BLK0        104              4
86      KEY_PURPOSE_5                   EFUSE_BLK0        108              4
87      SEC_DPA_LEVEL                   EFUSE_BLK0        112              2
88      SECURE_BOOT_EN                  EFUSE_BLK0        116              1
89      SECURE_BOOT_AGGRESSIVE_REVOKE   EFUSE_BLK0        117              1
90      KM_XTS_KEY_LENGTH_256           EFUSE_BLK0        123              1
91      FLASH_TPUW                      EFUSE_BLK0        124              4
92      DIS_DOWNLOAD_MODE               EFUSE_BLK0        128              1
93      DIS_DIRECT_BOOT                 EFUSE_BLK0        129              1
94      DIS_USB_SERIAL_JTAG_ROM_PRINT   EFUSE_BLK0        130              1
95      LOCK_KM_KEY                     EFUSE_BLK0        131              1
96      DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE       EFUSE_BLK0        132              1
97      ENABLE_SECURITY_DOWNLOAD        EFUSE_BLK0        133              1
98      UART_PRINT_CONTROL              EFUSE_BLK0        134              2
99      FORCE_SEND_RESUME               EFUSE_BLK0        136              1
100     SECURE_VERSION                  EFUSE_BLK0        137              16
101     SECURE_BOOT_DISABLE_FAST_WAKE   EFUSE_BLK0        153              1
102     HYS_EN_PAD                      EFUSE_BLK0        154              1
103     XTS_DPA_PSEUDO_LEVEL            EFUSE_BLK0        155              2
104     XTS_DPA_CLK_ENABLE              EFUSE_BLK0        157              1
105     HUK_GEN_STATE                   EFUSE_BLK0        160              9
106     XTAL_48M_SEL                    EFUSE_BLK0        169              3
107     XTAL_48M_SEL_MODE               EFUSE_BLK0        172              1
108     ECDSA_DISABLE_P192              EFUSE_BLK0        173              1
109     ECC_FORCE_CONST_TIME            EFUSE_BLK0        174              1
110     MAC                             EFUSE_BLK1         0               8
111     MAC                             EFUSE_BLK1         8               8
112     MAC                             EFUSE_BLK1         16              8
113     MAC                             EFUSE_BLK1         24              8
114     MAC                             EFUSE_BLK1         32              8
115     MAC                             EFUSE_BLK1         40              8
116     MAC_EXT                         EFUSE_BLK1         48              16
117     SYS_DATA_PART2                  EFUSE_BLK10        0              256
118     BLOCK_SYS_DATA1                 EFUSE_BLK2         0              256
119     USER_DATA                       EFUSE_BLK3         0              256
120     USER_DATA.MAC_CUSTOM            EFUSE_BLK3        200              48
121     KEY0                            EFUSE_BLK4         0              256
122     KEY1                            EFUSE_BLK5         0              256
123     KEY2                            EFUSE_BLK6         0              256
124     KEY3                            EFUSE_BLK7         0              256
125     KEY4                            EFUSE_BLK8         0              256
126     KEY5                            EFUSE_BLK9         0              256

Used bits in efuse table:
EFUSE_BLK0
[0 31] [0 0] [2 2] ... [40 41] [44 52] [57 58] [64 78] [80 113] [116 117] [123 157] [160 174]

EFUSE_BLK1
[0 63]

EFUSE_BLK10
[0 255]

EFUSE_BLK2
[0 255]

EFUSE_BLK3
[0 255] [200 247]

EFUSE_BLK4
[0 255]

EFUSE_BLK5
[0 255]

EFUSE_BLK6
[0 255]

EFUSE_BLK7
[0 255]

EFUSE_BLK8
[0 255]

EFUSE_BLK9
[0 255]
Note: Not printed ranges are free for using. (bits in EFUSE_BLK0 are reserved for Espressif)

不包含在方括号中的位是空闲的(一些位是乐鑫的保留位)。已检查所有字段的位重叠情况。

要在现有字段中添加子字段,请参考 结构化 eFuse 字段。例如,可使用 . 操作符将字段 SERIAL_NUMBERMODEL_NUMBERHARDWARE_REV 添加到现有的 USER_DATA 字段中,如下所示:

USER_DATA.SERIAL_NUMBER,                  EFUSE_BLK3,    0,  32,
USER_DATA.MODEL_NUMBER,                   EFUSE_BLK3,    32, 10,
USER_DATA.HARDWARE_REV,                   EFUSE_BLK3,    42, 10,

通常按照如下步骤添加新的 eFuse 字段:

  1. 在 CSV 文件中为每个 eFuse 字段添加一行记录。

  2. 运行 show_efuse_table 命令检查 eFuse 表。

  3. 如要生成源文件,运行 efuse_common_tableefuse_custom_table 命令。

如果遇到 intersects without of range 等错误,请参阅 结构化 eFuse 字段 中的解决办法。

位序

eFuse 位序采取小字节序(参见下方示例),这说明 eFuse 位按照从 LSB 到 MSB 的顺序进行读写:

$ idf.py efuse-dump

USER_DATA      (BLOCK3          ) [3 ] read_regs: 03020100 07060504 0B0A0908 0F0E0D0C 13121111 17161514 1B1A1918 1F1E1D1C
BLOCK4         (BLOCK4          ) [4 ] read_regs: 03020100 07060504 0B0A0908 0F0E0D0C 13121111 17161514 1B1A1918 1F1E1D1C

where is the register representation:

EFUSE_RD_USR_DATA0_REG = 0x03020100
EFUSE_RD_USR_DATA1_REG = 0x07060504
EFUSE_RD_USR_DATA2_REG = 0x0B0A0908
EFUSE_RD_USR_DATA3_REG = 0x0F0E0D0C
EFUSE_RD_USR_DATA4_REG = 0x13121111
EFUSE_RD_USR_DATA5_REG = 0x17161514
EFUSE_RD_USR_DATA6_REG = 0x1B1A1918
EFUSE_RD_USR_DATA7_REG = 0x1F1E1D1C

where is the byte representation:

byte[0] = 0x00, byte[1] = 0x01, ... byte[3] = 0x03, byte[4] = 0x04, ..., byte[31] = 0x1F

例如,CSV 文件描述了 USER_DATA 字段,该字段占用 256 位,即一个完整的块。

USER_DATA,          EFUSE_BLK3,    0,  256,     User data
USER_DATA.FIELD1,   EFUSE_BLK3,    16,  16,     Field1

ID,                 EFUSE_BLK4,    8,  3,      ID bit[0..2]
,                   EFUSE_BLK4,    16, 2,      ID bit[3..4]
,                   EFUSE_BLK4,    32, 3,      ID bit[5..7]

因此,读取如上 eFuse USER_DATA 块会得到以下结果:

uint8_t buf[32] = { 0 };
esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA, &buf, sizeof(buf) * 8);
// buf[0] = 0x00, buf[1] = 0x01, ... buf[31] = 0x1F

uint32_t field1 = 0;
size_t field1_size = ESP_EFUSE_USER_DATA[0]->bit_count; // 可以用于这种情况,因为它只包含一个条目
esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA, &field1, field1_size);
// field1 = 0x0302

uint32_t field1_1 = 0;
esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA, &field1_1, 2); // 只读取前两位
// field1 = 0x0002

uint8_t id = 0;
size_t id_size = esp_efuse_get_field_size(ESP_EFUSE_ID); // 返回 6
// size_t id_size = ESP_EFUSE_USER_DATA[0]->bit_count; // 不能用于这种情况,因为其中包含 3 个条目,会返回 3 而不是 6
esp_efuse_read_field_blob(ESP_EFUSE_ID, &id, id_size);
// id = 0x91
// b'100 10  001
//   [3] [2] [3]

uint8_t id_1 = 0;
esp_efuse_read_field_blob(ESP_EFUSE_ID, &id_1, 3);
// id = 0x01
// b'001

在构建阶段获取 eFuse 状态

要在项目的构建阶段获取 eFuse 状态,可以使用以下两个 CMake 函数:

  • espefuse_get_json_summary() - 调用 espefuse summary --format json 命令并返回一个 JSON 字符串(该字符串不存储在文件中)。

  • espefuse_get_efuse() - 在此 JSON 字符串中找到给定的 eFuse 名称并返回其属性。

该 JSON 字符串具有以下属性:

{
    "MAC": {
        "bit_len": 48,
        "block": 0,
        "category": "identity",
        "description": "Factory MAC Address",
        "efuse_type": "bytes:6",
        "name": "MAC",
        "pos": 0,
        "readable": true,
        "value": "94:b9:7e:5a:6e:58 (CRC 0xe2 OK)",
        "word": 1,
        "writeable": true
    },
}

可以通过项目顶层目录下的 CMakeLists.txt (system/efuse/CMakeLists.txt) 来使用这些函数:

# ...
project(hello_world)

espefuse_get_json_summary(efuse_json)
espefuse_get_efuse(ret_data ${efuse_json} "MAC" "value")
message("MAC:" ${ret_data})

value 属性的格式与 espefuse summaryidf.py efuse-summary 中显示的格式相同。

MAC:94:b9:7e:5a:6e:58 (CRC 0xe2 OK)

在示例测试 system/efuse/CMakeLists.txt 中,添加了一个自定义目标 efuse-filter。这样,不仅在项目构建阶段,而在任何时候都可以运行 idf.py efuse-filter 命令读取所需的 eFuse(在 efuse_names 列表中指定)。

调试 eFuse & 单元测试

虚拟 eFuse

Kconfig 选项 CONFIG_EFUSE_VIRTUAL 在 eFuse 管理器中虚拟了 eFuse 值,因此写入操作是仿真操作,不会永久更改 eFuse 值。这对于应用程序调试和单元测试很有用处。

在启动时,eFuses 被复制到 RAM 中。此时,所有的 eFuse 操作(读和写)都是通过 RAM 执行,而不是通过实际的 eFuse 寄存器执行的。

除了 CONFIG_EFUSE_VIRTUAL 选项外,还有 CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH 选项,该选项可将 eFuse 保留在 flash 内存中。要使用此模式,partition_table 在 partition.csv 中包含名为 efuse 的分区:

efuse_em, data, efuse,   ,   0x2000,

在启动阶段,eFuse 会从 flash 中复制到 RAM 中,在 flash 为空的情况下,则从实际的 eFuse 复制到 RAM 中,然后更新 flash。此选项能够在重启后仍然保留 eFuse,用于测试安全启动和 flash 加密功能。

flash 加密测试

flash 加密是一项硬件功能,需要物理烧录 eFuse keyFLASH_CRYPT_CNT。如果 flash 加密实际未启用,那么启用 CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH 选项只是提供了测试的可能性,而不会加密 flash 中的任何内容,即使日志中显示了加密操作。

为此,可使用 bootloader_flash_write() 函数。但是,如果运行应用程序时芯片已启用 flash 加密,或者以 CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH 选项创建了引导加载程序,则 flash 加密/解密操作会正常进行。这意味着数据写入加密 flash 分区时被加密,从加密分区读取时被解密。

espefuse

esptool 中包含一个用于读取/写入 ESP32-C5 eFuse 位的有用工具: espefuse

idf.py 命令也可以直接提供上述工具的部分功能。例如,运行 idf.py efuse-summary 命令,效果等同于 espefuse summary

idf.py -p PORT efuse-summary

Executing action: efuse-summary
(...)

=== Run "summary" command ===
EFUSE_NAME (Block) Description  = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Config fuses:
WR_DIS (BLOCK0)                                    Disable programming of individual eFuses           = 0 R/W (0x00000000)
RD_DIS (BLOCK0)                                    Disable reading from BlOCK4-10                     = 0 R/W (0b0000000)
DIS_ICACHE (BLOCK0)                                Represents whether icache is disabled or enabled.\ = False R/W (0b0)
                                                   \ 1: disabled\\ 0: enabled\\
DIS_TWAI (BLOCK0)                                  Represents whether TWAI function is disabled or en = False R/W (0b0)
                                                   abled.\\ 1: disabled\\ 0: enabled\\
KM_DISABLE_DEPLOY_MODE (BLOCK0)                    Represents whether the deploy mode of key manager  = 0 R/W (0x0)
                                                   is disable or not. \\ 1: disabled \\ 0: enabled.\\
KM_RND_SWITCH_CYCLE (BLOCK0)                       Set the bits to control key manager random number  = 0 R/W (0b00)
                                                   switch cycle. 0: control by register. 1: 8 km clk
                                                   cycles. 2: 16 km cycles. 3: 32 km cycles
KM_DEPLOY_ONLY_ONCE (BLOCK0)                       Set each bit to control whether corresponding key  = 0 R/W (0x0)
                                                   can only be deployed once. 1 is true; 0 is false.
                                                   bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds
DIS_DIRECT_BOOT (BLOCK0)                           Represents whether direct boot mode is disabled or = False R/W (0b0)
                                                    enabled.\\ 1: disabled\\ 0: enabled
UART_PRINT_CONTROL (BLOCK0)                        Set the default UARTboot message output mode       = Enable R/W (0b00)
HYS_EN_PAD (BLOCK0)                                Represents whether the hysteresis function of      = False R/W (0b0)
                                                   corresponding PAD is enabled.\\ 1: enabled\\ 0:disabled
HUK_GEN_STATE (BLOCK0)                             Set the bits to control validation of HUK generate = 0 R/W (0b000000000)
                                                    mode.\\ Odd of 1 is invalid.\\ Even of 1 is valid
XTAL_48M_SEL (BLOCK0)                              Represents whether XTAL frequency is 48MHz or not. = 0 R/W (0b000)
                                                    If not; 40MHz XTAL will be used. If this field co
                                                   ntains Odd number bit 1: Enable 48MHz XTAL\ Even n
                                                   umber bit 1: Enable 40MHz XTAL
XTAL_48M_SEL_MODE (BLOCK0)                         Specify the XTAL frequency selection is decided by = False R/W (0b0)
                                                    eFuse or strapping-PAD-state. 1: eFuse\\ 0: strap
                                                   ping-PAD-state
ECC_FORCE_CONST_TIME (BLOCK0)                      Represents whether to force ecc to use const-time  = False R/W (0b0)
                                                   calculation mode. \\ 1: Enable. \\ 0: Disable
BLOCK_SYS_DATA1 (BLOCK2)                           System data part 1 (reserved)
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK_USR_DATA (BLOCK3)                            User data
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK_SYS_DATA2 (BLOCK10)                          System data part 2 (reserved)
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

Flash fuses:
FLASH_TPUW (BLOCK0)                                Represents the flash waiting time after power-up;  = 0 R/W (0x0)
                                                   in unit of ms. When the value less than 15; the wa
                                                   iting time is the programmed value. Otherwise; the
                                                    waiting time is 2 times the programmed value
FORCE_SEND_RESUME (BLOCK0)                         Represents whether ROM code is forced to send a re = False R/W (0b0)
                                                   sume command during SPI boot.\\ 1: forced\\ 0:not
                                                   forced\\

Jtag fuses:
JTAG_SEL_ENABLE (BLOCK0)                           Represents whether the selection between usb_to_jt = False R/W (0b0)
                                                   ag and pad_to_jtag through strapping gpio15 when b
                                                   oth EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are
                                                   equal to 0 is enabled or disabled.\\ 1: enabled\\
                                                   0: disabled\\
SOFT_DIS_JTAG (BLOCK0)                             Represents whether JTAG is disabled in soft way.\\ = 0 R/W (0b000)
                                                    Odd number: disabled\\ Even number: enabled\\
DIS_PAD_JTAG (BLOCK0)                              Represents whether JTAG is disabled in the hard wa = False R/W (0b0)
                                                   y(permanently).\\ 1: disabled\\ 0: enabled\\

Mac fuses:
MAC (BLOCK1)                                       MAC address
   = 00:00:00:00:00:00 (OK) R/W
MAC_EXT (BLOCK1)                                   Represents the extended bits of MAC address        = 00:00 (OK) R/W
CUSTOM_MAC (BLOCK3)                                Custom MAC
   = 00:00:00:00:00:00 (OK) R/W
MAC_EUI64 (BLOCK1)                                 calc MAC_EUI64 = MAC[0]:MAC[1]:MAC[2]:MAC_EXT[0]:M
   = 00:00:00:00:00:00:00:00 (OK) R/W
                                                   AC_EXT[1]:MAC[3]:MAC[4]:MAC[5]

Security fuses:
DIS_FORCE_DOWNLOAD (BLOCK0)                        Represents whether the function that forces chip i = False R/W (0b0)
                                                   nto download mode is disabled or enabled.\\ 1: dis
                                                   abled\\ 0: enabled\\
SPI_DOWNLOAD_MSPI_DIS (BLOCK0)                     Represents whether SPI0 controller during boot_mod = False R/W (0b0)
                                                   e_download is disabled or enabled.\\ 1: disabled\\
                                                    0: enabled\\
DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0)               Represents whether flash encrypt function is disab = False R/W (0b0)
                                                   led or enabled(except in SPI boot mode).\\ 1: disa
                                                   bled\\ 0: enabled\\
FORCE_USE_KEY_MANAGER_KEY (BLOCK0)                 Set each bit to control whether corresponding key  = 0 R/W (0x0)
                                                   must come from key manager. 1 is true; 0 is false.
                                                    bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds
FORCE_DISABLE_SW_INIT_KEY (BLOCK0)                 Set this bit to disable software written init key; = False R/W (0b0)
                                                    and force use efuse_init_key
SPI_BOOT_CRYPT_CNT (BLOCK0)                        Enables flash encryption when 1 or 3 bits are set  = Disable R/W (0b000)
                                                   and disables otherwise
SECURE_BOOT_KEY_REVOKE0 (BLOCK0)                   Revoke 1st secure boot key                         = False R/W (0b0)
SECURE_BOOT_KEY_REVOKE1 (BLOCK0)                   Revoke 2nd secure boot key                         = False R/W (0b0)
SECURE_BOOT_KEY_REVOKE2 (BLOCK0)                   Revoke 3rd secure boot key                         = False R/W (0b0)
KEY_PURPOSE_0 (BLOCK0)                             Represents the purpose of Key0                     = USER R/W (0x0)
KEY_PURPOSE_1 (BLOCK0)                             Represents the purpose of Key1                     = USER R/W (0x0)
KEY_PURPOSE_2 (BLOCK0)                             Represents the purpose of Key2                     = USER R/W (0x0)
KEY_PURPOSE_3 (BLOCK0)                             Represents the purpose of Key3                     = USER R/W (0x0)
KEY_PURPOSE_4 (BLOCK0)                             Represents the purpose of Key4                     = USER R/W (0x0)
KEY_PURPOSE_5 (BLOCK0)                             Represents the purpose of Key5                     = USER R/W (0x0)
SEC_DPA_LEVEL (BLOCK0)                             Represents the spa secure level by configuring the = 0 R/W (0b00)
                                                    clock random divide mode
SECURE_BOOT_EN (BLOCK0)                            Represents whether secure boot is enabled or disab = False R/W (0b0)
                                                   led.\\ 1: enabled\\ 0: disabled\\
SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0)             Represents whether revoking aggressive secure boot = False R/W (0b0)
                                                    is enabled or disabled.\\ 1: enabled.\\ 0: disabled
KM_XTS_KEY_LENGTH_256 (BLOCK0)                     Set this bitto configure flash encryption use xts- = False R/W (0b0)
                                                   128 key. else use xts-256 key
DIS_DOWNLOAD_MODE (BLOCK0)                         Represents whether Download mode is disabled or en = False R/W (0b0)
                                                   abled.\\ 1: disabled\\ 0: enabled\\
LOCK_KM_KEY (BLOCK0)                               Represetns whether to lock the efuse xts key.\\ 1. = False R/W (0b0)
                                                    Lock\\ 0: Unlock\\
ENABLE_SECURITY_DOWNLOAD (BLOCK0)                  Represents whether security download is enabled or = False R/W (0b0)
                                                    disabled.\\ 1: enabled\\ 0: disabled\\
SECURE_VERSION (BLOCK0)                            Represents the version used by ESP-IDF anti-rollba = 0 R/W (0x0000)
                                                   ck feature
SECURE_BOOT_DISABLE_FAST_WAKE (BLOCK0)             Represents whether FAST VERIFY ON WAKE is disabled = False R/W (0b0)
                                                    or enabled when Secure Boot is enabled.\\ 1: disa
                                                   bled\\ 0: enabled\\
XTS_DPA_PSEUDO_LEVEL (BLOCK0)                      Represents the pseudo round level of xts-aes anti- = 0 R/W (0b00)
                                                   dpa attack.\\ 3: High.\\ 2: Moderate 1. Low\\ 0: D
                                                   isabled\\
XTS_DPA_CLK_ENABLE (BLOCK0)                        Represents whether xts-aes anti-dpa attack clock i = False R/W (0b0)
                                                   s enabled.\\ 1. Enable.\\ 0: Disable.\\
ECDSA_DISABLE_P192 (BLOCK0)                        Represents whether to disable P192 curve in ECDSA. = False R/W (0b0)
                                                   \\ 1: Disabled.\\ 0: Not disable
BLOCK_KEY0 (BLOCK4)
  Purpose: USER
               Key0 or user data
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK_KEY1 (BLOCK5)
  Purpose: USER
               Key1 or user data
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK_KEY2 (BLOCK6)
  Purpose: USER
               Key2 or user data
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK_KEY3 (BLOCK7)
  Purpose: USER
               Key3 or user data
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK_KEY4 (BLOCK8)
  Purpose: USER
               Key4 or user data
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK_KEY5 (BLOCK9)
  Purpose: USER
               Key5 or user data
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

Usb fuses:
DIS_USB_JTAG (BLOCK0)                              Represents whether the function of usb switch to j = False R/W (0b0)
                                                   tag is disabled or enabled.\\ 1: disabled\\ 0: ena
                                                   bled\\
USB_EXCHG_PINS (BLOCK0)                            Represents whether the D+ and D- pins is exchanged = False R/W (0b0)
                                                   .\\ 1: exchanged\\ 0: not exchanged\\
DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0)             Represents whether print from USB-Serial-JTAG is d = False R/W (0b0)
                                                   isabled or enabled.\\ 1: disabled\\ 0: enabled\\
DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0)         Represents whether the USB-Serial-JTAG download fu = False R/W (0b0)
                                                   nction is disabled or enabled.\\ 1: Disable\\ 0: E
                                                   nable\\

Vdd fuses:
VDD_SPI_AS_GPIO (BLOCK0)                           Represents whether vdd spi pin is functioned as gp = False R/W (0b0)
                                                   io.\\ 1: functioned\\ 0: not functioned\\

Wdt fuses:
WDT_DELAY_SEL (BLOCK0)                             Represents the threshold level of the RTC watchdog = 0 R/W (0b00)
                                                    STG0 timeout.\\ 0: Original threshold configurati
                                                   on value of STG0 *2 \\1: Original threshold config
                                                   uration value of STG0 *4 \\2: Original threshold c
                                                   onfiguration value of STG0 *8 \\3: Original thresh
                                                   old configuration value of STG0 *16 \\

获取所有 eFuse 寄存器的转储数据。

idf.py efuse-dump

Executing action: efuse-dump
Running espefuse in directory <project-directory>
Executing "espefuse dump --chip esp32c5"...
espefuse v5.0.2
Connecting....

=== Run "dump" command ===
BLOCK0          (                ) [0 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000
MAC_SPI_8M_0    (BLOCK1          ) [1 ] read_regs: f9f95440 fffe6055 00000000 00000000 00000000 00000000
BLOCK_SYS_DATA  (BLOCK2          ) [2 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_USR_DATA  (BLOCK3          ) [3 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY0      (BLOCK4          ) [4 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY1      (BLOCK5          ) [5 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY2      (BLOCK6          ) [6 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY3      (BLOCK7          ) [7 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY4      (BLOCK8          ) [8 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY5      (BLOCK9          ) [9 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_SYS_DATA2 (BLOCK10         ) [10] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

BLOCK0          (                ) [0 ] err__regs: 00000000 00000000 00000000 00000000 00000000 00000000
EFUSE_RD_RS_ERR0_REG        0x00000000
EFUSE_RD_RS_ERR1_REG        0x00000000

延迟烧写 WR_DIS

WR_DIS (写禁用)是一个特殊的 eFuse 字段,用于实现永久写保护。WR_DIS 中的每个位用于禁止进一步烧写一个(或多个)关联的 eFuse 字段。一旦完成烧写,将无法再修改受影响的 eFuse 字段。

烧写 BLOCK0 中的暂存数据时,WR_DIS 的各个位会在所有其他 BLOCK0 数据烧写完成后单独烧写,以确保在出现编码错误时,烧写函数能够通过重试机制进行恢复。这种方式保证了仅在其他 BLOCK0 数据成功烧写后,才对其施加写保护。

Token Dump

eFuse Token 转储 功能提供了一种紧凑的、单行的 eFuse 状态表示,可以从设备日志中复制并在主机上稍后解码。这适用于无法或不便直接使用主机工具读取 eFuse 的情况(例如,UART 下载被禁用、安全下载已启用、安全启动/flash 加密已部署或设备在远程位置)。

EFSR:esp32c3:004:AAGAAAEAAAAAAAAEAAAAAAAAAAAAAAAA:AAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAA:AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA::::::::::epNVBg

Token 可以表示:

  • 当前烧写的 eFuse(读快照,EFSR),

  • 暂存(尚未烧写)的写入集(写快照,EFSW)— 在批量写入模式下,可以在调用 esp_efuse_batch_write_commit() 之前转储待写入的数据,

  • 单个 token 中同时包含已烧写的 eFuse 和暂存写入的综合快照(EFSRW)。

Token 包括一个 CRC32 校验和,用于检测截断和意外修改。

典型用例

  • 生产/现场诊断: 从锁定的设备导出 eFuse 状态并离线解码。

  • 烧写后验证: 确认生产步骤后的安全配置和密钥目的。

  • 编码错误调查: 捕获和共享编码错误寄存器快照以及块数据。

  • 审计和可追溯性: 将 token 作为配置工件存储以供后续审查。

  • 暂存写入转移: 在固件(或主机)中生成 EFSW token,稍后使用受控工作流应用。

支持的工作流

  • 在设备上:

  • 在主机上:

    • espefuse --token EFS... summary — 解码 token 并显示 eFuse 摘要,无需连接到设备。

    • espefuse dump --format EFSR — 从已连接芯片生成 EFSR token 用于共享/备份。

    • espefuse burn-efuse ... --show-token — 生成表示暂存写入的 EFSW token。

安全注意事项

重要

Token 未加密。将 token 视为敏感数据:

  • Token 可能包含 唯一标识符 (例如 MAC/UUID 类字段)和 安全相关配置位 (安全启动、flash 加密、JTAG/UART 禁用、密钥用途)。

  • EFSW token 代表 暂存写入 。由于暂存视图展示的是尚未烧写、也尚未受 eFuse 读保护位保护的值,它们可能包含 明文只写密钥数据 (例如 flash 加密密钥或其他在烧写后会被读保护的密钥)。这会在永久锁定前泄露配置意图和秘密材料。

  • EFSRW token 包含同样的暂存部分,因此也具有相同的明文密钥暴露风险。

  • 即使某些 eFuse 在目标上受读保护,token 仍可能携带 操作敏感值

如果固件暴露用于在控制台、远程端点或其他运行时 API 中打印 eFuse token 的接口,固件必须在生成 token 前对该请求进行身份认证和授权。

建议:

  • 仅与信任方通过信任渠道共享 token(避免公开问题跟踪器)。

  • 像存储其他生产/配置工件那样存储 token(限制访问、限制保留期)。

  • 优先使用 EFSR token 进行诊断和审计;仅当明确需要转移暂存写入状态时才使用 EFSW token。

Token 格式

Token 是一个冒号分隔的序列:

<token_name>:<chip>:<ver>:<b64_block0>:...:<b64_blockN>:<b64_cerr>:<b64_crc32>

字段说明:

  • token_nameEFSREFSWEFSRW 之一。

  • chip — 芯片名称(小写,不含破折号),例如 esp32c3

  • ver — 芯片版本为三位十进制数字(前导零),例如 004。由主版本和次版本字段使用公式 ver = major * 100 + minor 构造,其中主版本占据第一位数字,次版本占据最后两位数字。

  • b64_block0 ... b64_blockN — Base64URL 编码的按块数据。每个块是 32 位字的连接(小端序)。块数不在格式中显式编码,而是从芯片类型派生的。块数可通过计数 token 中的冒号分隔符(:)来确定。空块表示为连续冒号(::)。

  • b64_cerr — 可选的 Base64URL 编码编码错误寄存器快照。如果没有错误,可能为空。

  • b64_crc32 — Base64URL 编码的 CRC32,覆盖整个 token "<token_name>:<chip>:<ver>:<b64_block0>:...:<b64_blockN>:<b64_cerr>:". CRC32 以小端序存储并编码为无填充 Base64URL。

Token 只能在使用与其创建目标相同的目标进行处理时才能正确解码和解释。ESP-IDF API 和 espefuse 验证并依赖于以下字段:芯片名称、芯片版本和块布局,以及 CRC32 完整性。如果这些不符合目标芯片,可能会导致解码错误或丢失字段。

Base64URL 使用与 Base64 相同的字母表,但将 + 替换为 -,将 / 替换为 _,并省略填充(=)。

在设备上生成 Token

使用 esp_efuse_token_dump() 在缓冲区中创建 token 或将其打印到日志:

char token[1024]; /* 大小取决于目标和 eFuse */
esp_efuse_token_type_t token_type = ESP_EFUSE_TOKEN_FROM_READ;
ESP_ERROR_CHECK(esp_efuse_token_dump(token_type, token, sizeof(token)));
ESP_LOGI(TAG, "IDF_MONITOR_EXECUTE_ESPEFUSE_SUMMARY %s", token);

Token 类型值:

  • ESP_EFUSE_TOKEN_FROM_READ — 已烧写的 eFuse 的 token(以 EFSR 开头)。

  • ESP_EFUSE_TOKEN_FROM_STAGED — 暂存写入的 token(以 EFSW 开头)。它会显示尚未烧写、也尚未受读保护的值,因此可能以明文暴露密钥。需要启用 CONFIG_EFUSE_ENABLE_STAGED_TOKEN_API。仅此类型可被烧写回。

  • ESP_EFUSE_TOKEN_FROM_READ_STAGED — 组合 token(以 EFSRW 开头)。它包含同样的暂存部分,因此也具有相同的明文密钥暴露风险。需要启用 CONFIG_EFUSE_ENABLE_STAGED_TOKEN_API

如果 buf == NULL,token 将打印到控制台(INFO 级别),不包含颜色、标签或时间戳。

在设备上烧写 Token

使用 esp_efuse_token_burn() 在设备上应用 EFSW token,通过烧写 token 中编码的暂存 eFuse 写入。该函数验证 token 完整性(CRC32)并使用芯片名称和版本检查兼容性。如果 主要 wafer 版本与目标芯片不匹配,token 将被拒绝。要绕过版本检查,请使用忽略参数。烧写 token 的示例:

esp_efuse_batch_write_begin();
esp_efuse_token_burn(token, false);  // 设置为 true 以忽略主版本不匹配
esp_efuse_batch_write_commit();

仅当您知道 token 是为相同 eFuse 布局生成的(例如相同目标,仅 wafer 次版本不同)时,才可跳过主版本检查;在这种情况下,token 版本可能仅在最后两位数字上不同,而第一位数字(主版本)必须正常匹配。

ESP-IDF 监视器集成

运行 idf.py monitor 时,如果日志行以以下标记之一开头,主机可以自动解码目标打印的 eFuse token 并以内联方式显示结果:

  • IDF_MONITOR_EXECUTE_ESPEFUSE_SUMMARYespefuse --token {ARGS} summary --active

  • IDF_MONITOR_EXECUTE_ESPEFUSE_DUMPespefuse --token <TOKEN> dump

{ARGS} 必须包含 eFuse token(EFSR/EFSW/EFSRW),并可能包含 --extend-efuse-table <csv> 以加载自定义 eFuse 定义。

示例:以下显示使用 --active 执行 summary 命令,仅显示非零 eFuse 字段以减少输出大小。--extend-efuse-table 选项加载自定义 eFuse 表定义:

I (441) example: IDF_MONITOR_EXECUTE_ESPEFUSE_SUMMARY EFSR:esp32c3:100:AAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA:zIH3-VVgAAAAAAAAAAAAS8kmEVKwQgYB:ZSd8yloMSAJssOWmfZQw8lFbphuTZH574QcV3ggAAAA:AAAAAAAAAAEayAcAAAAAAAAAAAAAAAAAAAAAAAAAAAA:::::::::ydrNkQ --extend-efuse-table main/esp_efuse_custom_table.csv

 --- Executing monitor command: espefuse --token EFSR:esp32c3:100:AAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA:zIH3-VVgAAAAAAAAAAAAS8kmEVKwQgYB:ZSd8yloMSAJssOWmfZQw8lFbphuTZH574QcV3ggAAAA:AAAAAAAAAAEayAcAAAAAAAAAAAAAAAAAAAAAAAAAAAA:::::::::ydrNkQ --extend-efuse-table main/esp_efuse_custom_table.csv summary --active
 espefuse v5.1.0

 === Run "summary" command ===
 EFUSE_NAME (Block) Description  = [Meaningful Value] [Readable/Writeable] (Hex Value)
 ————————————————————————————————————————————————————————————————————————————————————————
 Calibration fuses:
 K_RTC_LDO (BLOCK1)                                 BLOCK1 K_RTC_LDO                                   = 77 R/W (0b1001101)
 K_DIG_LDO (BLOCK1)                                 BLOCK1 K_DIG_LDO                                   = 68 R/W (0b1000100)
 V_RTC_DBIAS20 (BLOCK1)                             BLOCK1 voltage of rtc dbias20                      = 144 R/W (0x90)
 V_DIG_DBIAS20 (BLOCK1)                             BLOCK1 voltage of digital dbias20                  = 130 R/W (0x82)
 DIG_DBIAS_HVT (BLOCK1)                             BLOCK1 digital dbias when hvt                      = 21 R/W (0b10101)
 THRES_HVT (BLOCK1)                                 BLOCK1 pvt threshold when hvt                      = 400 R/W (0b0110010000)
 TEMP_CALIB (BLOCK2)                                Temperature calibration data                       = -10.600000000000001 R/W (0b101101010)
 OCODE (BLOCK2)                                     ADC OCode                                          = 101 R/W (0x65)
 ADC1_INIT_CODE_ATTEN0 (BLOCK2)                     ADC1 init code at atten0                           = 442 R/W (0b0110111010)
 ADC1_INIT_CODE_ATTEN1 (BLOCK2)                     ADC1 init code at atten1                           = 588 R/W (0b1001001100)
 ADC1_INIT_CODE_ATTEN2 (BLOCK2)                     ADC1 init code at atten2                           = 612 R/W (0b1001100100)
 ADC1_INIT_CODE_ATTEN3 (BLOCK2)                     ADC1 init code at atten3                           = 735 R/W (0b1011011111)
 ADC1_CAL_VOL_ATTEN0 (BLOCK2)                       ADC1 calibration voltage at atten0                 = 535 R/W (0b1000010111)
 ADC1_CAL_VOL_ATTEN1 (BLOCK2)                       ADC1 calibration voltage at atten1                 = 31 R/W (0b0000011111)
 ADC1_CAL_VOL_ATTEN2 (BLOCK2)                       ADC1 calibration voltage at atten2                 = 533 R/W (0b1000010101)
 ADC1_CAL_VOL_ATTEN3 (BLOCK2)                       ADC1 calibration voltage at atten3                 = 567 R/W (0b1000110111)

 Config fuses:
 ERR_RST_ENABLE (BLOCK0)                            Use BLOCK0 to check error record registers         = with check R/W (0b1)
 BLOCK_USR_DATA (BLOCK3)                            User data
 = 00 00 00 00 00 00 00 01 1a c8 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

 Flash fuses:
 FLASH_CAP (BLOCK1)                                 Flash capacity                                     = 4M R/W (0b001)
 FLASH_TEMP (BLOCK1)                                Flash temperature                                  = 105C R/W (0b01)
 FLASH_VENDOR (BLOCK1)                              Flash vendor                                       = XMC R/W (0b001)

 Identity fuses:
 BLK_VERSION_MINOR (BLOCK1)                         BLK_VERSION_MINOR                                  = 3 R/W (0b011)
 WAFER_VERSION_MAJOR (BLOCK1)                       WAFER_VERSION_MAJOR                                = 1 R/W (0b01)
 OPTIONAL_UNIQUE_ID (BLOCK2)                        Optional unique 128-bit ID
 = 65 27 7c ca 5a 0c 48 02 6c b0 e5 a6 7d 94 30 f2 R/W
 BLK_VERSION_MAJOR (BLOCK2)                         BLK_VERSION_MAJOR of BLOCK2                        = With calibration R/W (0b01)

 Mac fuses:
 MAC (BLOCK1)                                       MAC address
 = 60:55:f9:f7:81:cc (OK) R/W

 User fuses:
 MODULE_VERSION (BLOCK3)                            Module version (56-63)                             = 1 R/W (0x01)
 DEVICE_ROLE (BLOCK3)                               Device role (64-66)                                = 2 R/W (0b010)
 SETTING_1 (BLOCK3)                                 Setting 1 (67-72)                                  = 3 R/W (0b000011)
 SETTING_2 (BLOCK3)                                 Setting 2 (73-77)                                  = 4 R/W (0b00100)
 CUSTOM_SECURE_VERSION (BLOCK3)                     Custom secure version (78-93)                      = 31 R/W (0x001f)
 ...

dump 示例:

I (441) example: IDF_MONITOR_EXECUTE_ESPEFUSE_DUMP EFSR:esp32c3:100:AAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA:zIH3-VVgAAAAAAAAAAAAS8kmEVKwQgYB:ZSd8yloMSAJssOWmfZQw8lFbphuTZH574QcV3ggAAAA:AAAAAAAAAAEayAcAAAAAAAAAAAAAAAAAAAAAAAAAAAA:::::::::ydrNkQ

--- Executing monitor command: espefuse --token EFSR:esp32c3:100:AAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA:zIH3-VVgAAAAAAAAAAAAS8kmEVKwQgYB:ZSd8yloMSAJssOWmfZQw8lFbphuTZH574QcV3ggAAAA:AAAAAAAAAAEayAcAAAAAAAAAAAAAAAAAAAAAAAAAAAA:::::::::ydrNkQ dump
espefuse v5.1.0

=== Run "dump" command ===
BLOCK0          (                ) [0 ] dump: 00000000 00000000 00000000 00000000 80000000 00000000
MAC_SPI_8M_0    (BLOCK1          ) [1 ] dump: f9f781cc 00006055 00000000 4b000000 521126c9 010642b0
BLOCK_SYS_DATA  (BLOCK2          ) [2 ] dump: ca7c2765 02480c5a a6e5b06c f230947d 1ba65b51 7b7e6493 de1507e1 00000008
BLOCK_USR_DATA  (BLOCK3          ) [3 ] dump: 00000000 01000000 0007c81a 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY0      (BLOCK4          ) [4 ] dump: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY1      (BLOCK5          ) [5 ] dump: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY2      (BLOCK6          ) [6 ] dump: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY3      (BLOCK7          ) [7 ] dump: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY4      (BLOCK8          ) [8 ] dump: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_KEY5      (BLOCK9          ) [9 ] dump: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK_SYS_DATA2 (BLOCK10         ) [10] dump: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

应用示例

  • system/efuse 演示了如何在 ESP32-C5 上使用 eFuse API,展示了从通用和自定义 eFuse 表中读取和写入字段的操作,并解释了虚拟 eFuse 在调试中的用途。

API 参考

Header File

  • components/efuse/esp32c5/include/esp_efuse_chip.h

  • This header file can be included with:

    #include "esp_efuse_chip.h"
    
  • This header file is a part of the API provided by the efuse component. To declare that your component depends on efuse, add the following to your CMakeLists.txt:

    REQUIRES efuse
    

    or

    PRIV_REQUIRES efuse
    

Enumerations

enum esp_efuse_block_t

Type of eFuse blocks ESP32C5.

Values:

enumerator EFUSE_BLK0

Number of eFuse BLOCK0. REPEAT_DATA

enumerator EFUSE_BLK1

Number of eFuse BLOCK1. MAC_SPI_8M_SYS

enumerator EFUSE_BLK2

Number of eFuse BLOCK2. SYS_DATA_PART1

enumerator EFUSE_BLK_SYS_DATA_PART1

Number of eFuse BLOCK2. SYS_DATA_PART1

enumerator EFUSE_BLK3

Number of eFuse BLOCK3. USER_DATA

enumerator EFUSE_BLK_USER_DATA

Number of eFuse BLOCK3. USER_DATA

enumerator EFUSE_BLK4

Number of eFuse BLOCK4. KEY0

enumerator EFUSE_BLK_KEY0

Number of eFuse BLOCK4. KEY0

enumerator EFUSE_BLK5

Number of eFuse BLOCK5. KEY1

enumerator EFUSE_BLK_KEY1

Number of eFuse BLOCK5. KEY1

enumerator EFUSE_BLK6

Number of eFuse BLOCK6. KEY2

enumerator EFUSE_BLK_KEY2

Number of eFuse BLOCK6. KEY2

enumerator EFUSE_BLK7

Number of eFuse BLOCK7. KEY3

enumerator EFUSE_BLK_KEY3

Number of eFuse BLOCK7. KEY3

enumerator EFUSE_BLK8

Number of eFuse BLOCK8. KEY4

enumerator EFUSE_BLK_KEY4

Number of eFuse BLOCK8. KEY4

enumerator EFUSE_BLK9

Number of eFuse BLOCK9. KEY5

enumerator EFUSE_BLK_KEY5

Number of eFuse BLOCK9. KEY5

enumerator EFUSE_BLK_KEY_MAX
enumerator EFUSE_BLK10

Number of eFuse BLOCK10. SYS_DATA_PART2

enumerator EFUSE_BLK_SYS_DATA_PART2

Number of eFuse BLOCK10. SYS_DATA_PART2

enumerator EFUSE_BLK_MAX
enum esp_efuse_coding_scheme_t

Type of coding scheme.

Values:

enumerator EFUSE_CODING_SCHEME_NONE

None

enumerator EFUSE_CODING_SCHEME_RS

Reed-Solomon coding

enum esp_efuse_purpose_t

Type of key purpose.

Values:

enumerator ESP_EFUSE_KEY_PURPOSE_USER

User purposes (software-only use)

enumerator ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY

ECDSA private key (P256) (Expected in little endian order)

enumerator ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P256

ECDSA private key (P256) (Expected in little endian order)

enumerator ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY

XTS_AES_128_KEY (flash/PSRAM encryption)

enumerator ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL

HMAC Downstream mode

enumerator ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG

JTAG soft enable key (uses HMAC Downstream mode)

enumerator ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE

Digital Signature peripheral key (uses HMAC Downstream mode)

enumerator ESP_EFUSE_KEY_PURPOSE_HMAC_UP

HMAC Upstream mode

enumerator ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0

SECURE_BOOT_DIGEST0 (Secure Boot key digest)

enumerator ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1

SECURE_BOOT_DIGEST1 (Secure Boot key digest)

enumerator ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2

SECURE_BOOT_DIGEST2 (Secure Boot key digest)

enumerator ESP_EFUSE_KEY_PURPOSE_KM_INIT_KEY

KM_INIT_KEY (Key Manager initialization key)

enumerator ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_PSRAM_KEY

XTS_AES_128_PSRAM_KEY (PSRAM encryption)

enumerator ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P192

ECDSA private key (P192)

enumerator ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_L

ECDSA private key (P384)

enumerator ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_H

ECDSA private key (P384)

enumerator ESP_EFUSE_KEY_PURPOSE_MAX

MAX PURPOSE

Header File

  • components/efuse/include/esp_efuse.h

  • This header file can be included with:

    #include "esp_efuse.h"
    
  • This header file is a part of the API provided by the efuse component. To declare that your component depends on efuse, add the following to your CMakeLists.txt:

    REQUIRES efuse
    

    or

    PRIV_REQUIRES efuse
    

Functions

esp_err_t esp_efuse_read_field_blob(const esp_efuse_desc_t *field[], void *dst, size_t dst_size_bits)

Reads bits from EFUSE field and writes it into an array.

The number of read bits will be limited to the minimum value from the description of the bits in "field" structure or "dst_size_bits" required size. Use "esp_efuse_get_field_size()" function to determine the length of the field.

备注

Please note that reading in the batch mode does not show uncommitted changes.

参数:
  • field -- [in] A pointer to the structure describing the fields of efuse.

  • dst -- [out] A pointer to array that will contain the result of reading.

  • dst_size_bits -- [in] The number of bits required to read. If the requested number of bits is greater than the field, the number will be limited to the field size.

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

bool esp_efuse_read_field_bit(const esp_efuse_desc_t *field[])

Read a single bit eFuse field as a boolean value.

备注

The value must exist and must be a single bit wide. If there is any possibility of an error in the provided arguments, call esp_efuse_read_field_blob() and check the returned value instead.

备注

If assertions are enabled and the parameter is invalid, execution will abort

备注

Please note that reading in the batch mode does not show uncommitted changes.

参数:

field -- [in] A pointer to the structure describing the fields of efuse.

返回:

  • true: The field parameter is valid and the bit is set.

  • false: The bit is not set, or the parameter is invalid and assertions are disabled.

esp_err_t esp_efuse_read_field_cnt(const esp_efuse_desc_t *field[], size_t *out_cnt)

Reads bits from EFUSE field and returns number of bits programmed as "1".

If the bits are set not sequentially, they will still be counted.

备注

Please note that reading in the batch mode does not show uncommitted changes.

参数:
  • field -- [in] A pointer to the structure describing the fields of efuse.

  • out_cnt -- [out] A pointer that will contain the number of programmed as "1" bits.

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

esp_err_t esp_efuse_write_field_blob(const esp_efuse_desc_t *field[], const void *src, size_t src_size_bits)

Writes array to EFUSE field.

The number of write bits will be limited to the minimum value from the description of the bits in "field" structure or "src_size_bits" required size. Use "esp_efuse_get_field_size()" function to determine the length of the field. After the function is completed, the writing registers are cleared.

参数:
  • field -- [in] A pointer to the structure describing the fields of efuse.

  • src -- [in] A pointer to array that contains the data for writing.

  • src_size_bits -- [in] The number of bits required to write.

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

esp_err_t esp_efuse_write_field_cnt(const esp_efuse_desc_t *field[], size_t cnt)

Writes a required count of bits as "1" to EFUSE field.

If there are no free bits in the field to set the required number of bits to "1", ESP_ERR_EFUSE_CNT_IS_FULL error is returned, the field will not be partially recorded. After the function is completed, the writing registers are cleared.

参数:
  • field -- [in] A pointer to the structure describing the fields of efuse.

  • cnt -- [in] Required number of programmed as "1" bits.

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_CNT_IS_FULL: Not all requested cnt bits is set.

esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t *field[])

Write a single bit eFuse field to 1.

For use with eFuse fields that are a single bit. This function will write the bit to value 1 if it is not already set, or does nothing if the bit is already set.

This is equivalent to calling esp_efuse_write_field_cnt() with the cnt parameter equal to 1, except that it will return ESP_OK if the field is already set to 1.

参数:

field -- [in] Pointer to the structure describing the efuse field.

返回:

  • ESP_OK: The operation was successfully completed, or the bit was already set to value 1.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments, including if the efuse field is not 1 bit wide.

esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)

Sets a write protection for the whole block.

After that, it is impossible to write to this block. The write protection does not apply to block 0.

参数:

blk -- [in] Block number of eFuse. (EFUSE_BLK1, EFUSE_BLK2 and EFUSE_BLK3)

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_CNT_IS_FULL: Not all requested cnt bits is set.

  • ESP_ERR_NOT_SUPPORTED: The block does not support this command.

  • ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field.

esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)

Sets a read protection for the whole block.

After that, it is impossible to read from this block. The read protection does not apply to block 0.

参数:

blk -- [in] Block number of eFuse. (EFUSE_BLK1, EFUSE_BLK2 and EFUSE_BLK3)

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_CNT_IS_FULL: Not all requested cnt bits is set.

  • ESP_ERR_NOT_SUPPORTED: The block does not support this command.

int esp_efuse_get_field_size(const esp_efuse_desc_t *field[])

Returns the number of bits used by field.

参数:

field -- [in] A pointer to the structure describing the fields of efuse.

返回:

Returns the number of bits used by field.

uint32_t esp_efuse_read_reg(esp_efuse_block_t blk, unsigned int num_reg)

Returns value of efuse register.

This is a thread-safe implementation. Example: EFUSE_BLK2_RDATA3_REG where (blk=2, num_reg=3)

备注

Please note that reading in the batch mode does not show uncommitted changes.

参数:
  • blk -- [in] Block number of eFuse.

  • num_reg -- [in] The register number in the block.

返回:

Value of register

esp_err_t esp_efuse_write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint32_t val)

Write value to efuse register.

Apply a coding scheme if necessary. This is a thread-safe implementation. Example: EFUSE_BLK3_WDATA0_REG where (blk=3, num_reg=0)

参数:
  • blk -- [in] Block number of eFuse.

  • num_reg -- [in] The register number in the block.

  • val -- [in] Value to write.

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)

Return efuse coding scheme for blocks.

备注

The coding scheme is applicable only to 1, 2 and 3 blocks. For 0 block, the coding scheme is always NONE.

参数:

blk -- [in] Block number of eFuse.

返回:

Return efuse coding scheme for blocks

esp_err_t esp_efuse_read_block(esp_efuse_block_t blk, void *dst_key, size_t offset_in_bits, size_t size_bits)

Read key to efuse block starting at the offset and the required size.

备注

Please note that reading in the batch mode does not show uncommitted changes.

参数:
  • blk -- [in] Block number of eFuse.

  • dst_key -- [in] A pointer to array that will contain the result of reading.

  • offset_in_bits -- [in] Start bit in block.

  • size_bits -- [in] The number of bits required to read.

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

esp_err_t esp_efuse_write_block(esp_efuse_block_t blk, const void *src_key, size_t offset_in_bits, size_t size_bits)

Write key to efuse block starting at the offset and the required size.

参数:
  • blk -- [in] Block number of eFuse.

  • src_key -- [in] A pointer to array that contains the key for writing.

  • offset_in_bits -- [in] Start bit in block.

  • size_bits -- [in] The number of bits required to write.

返回:

  • ESP_OK: The operation was successfully completed.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits

uint32_t esp_efuse_get_pkg_ver(void)

Returns chip package from efuse.

返回:

chip package

esp_err_t esp_efuse_set_recovery_bootloader_offset(const uint32_t offset)

Sets the recovery bootloader flash offset in eFuse.

This function is used to set the flash offset in eFuse for the recovery bootloader. If an offset is already set in eFuse, it will be validated against the provided offset.

参数:

offset -- Flash offset where the recovery bootloader is located.

返回:

  • ESP_OK: Successfully set or given offset is already set.

  • ESP_ERR_NOT_ALLOWED: Recovery bootloader feature is disabled in eFuse.

  • ESP_FAIL: Failed to update the recovery bootloader flash offset.

  • Error code from eFuse read/write operations if an error occurs.

void esp_efuse_reset(void)

Reset efuse write registers.

Efuse write registers are written to zero, to negate any changes that have been staged here.

备注

This function is not threadsafe, if calling code updates efuse values from multiple tasks then this is caller's responsibility to serialise.

esp_err_t esp_efuse_disable_rom_download_mode(void)

Disable ROM Download Mode via eFuse.

Permanently disables the ROM Download Mode feature. Once disabled, if the SoC is booted with strapping pins set for ROM Download Mode then an error is printed instead.

备注

Not all SoCs support this option. An error will be returned if called on an ESP32 with a silicon revision lower than 3, as these revisions do not support this option.

备注

If ROM Download Mode is already disabled, this function does nothing and returns success.

返回:

  • ESP_OK If the eFuse was successfully burned, or had already been burned.

  • ESP_ERR_NOT_SUPPORTED (ESP32 only) This SoC is not capable of disabling UART download mode

  • ESP_ERR_INVALID_STATE (ESP32 only) This eFuse is write protected and cannot be written

esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme)

Set boot ROM log scheme via eFuse.

备注

By default, the boot ROM will always print to console. This API can be called to set the log scheme only once per chip, once the value is changed from the default it can't be changed again.

参数:

log_scheme -- Supported ROM log scheme

返回:

  • ESP_OK If the eFuse was successfully burned, or had already been burned.

  • ESP_ERR_NOT_SUPPORTED (ESP32 only) This SoC is not capable of setting ROM log scheme

  • ESP_ERR_INVALID_STATE This eFuse is write protected or has been burned already

esp_err_t esp_efuse_enable_rom_secure_download_mode(void)

Switch ROM Download Mode to Secure Download mode via eFuse.

Permanently enables Secure Download mode. This mode limits the use of ROM Download Mode functions to simple flash read, write and erase operations, plus a command to return a summary of currently enabled security features.

备注

If Secure Download mode is already enabled, this function does nothing and returns success.

备注

If UART DL mode is completely disabled then Secure Download mode can not be enabled and this API simply returns success.

返回:

  • ESP_OK If the eFuse was successfully burned, or had already been burned, or UART DL mode is already disabled.

  • Other errors If an error occurred while burning ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD.

uint32_t esp_efuse_read_secure_version(void)

Return secure_version from efuse field.

返回:

Secure version from efuse field

bool esp_efuse_check_secure_version(uint32_t secure_version)

Check secure_version from app and secure_version and from efuse field.

参数:

secure_version -- Secure version from app.

返回:

  • True: If version of app is equal or more then secure_version from efuse.

esp_err_t esp_efuse_update_secure_version(uint32_t secure_version)

Write efuse field by secure_version value.

Update the secure_version value is available if the coding scheme is None. Note: Do not use this function in your applications. This function is called as part of the other API.

参数:

secure_version -- [in] Secure version from app.

返回:

  • ESP_OK: Successful.

  • ESP_FAIL: secure version of app cannot be set to efuse field.

  • ESP_ERR_NOT_SUPPORTED: Anti rollback is not supported with the 3/4 and Repeat coding scheme.

esp_err_t esp_efuse_batch_write_begin(void)

Set the batch mode of writing fields.

This mode allows you to write the fields in the batch mode when need to burn several efuses at one time. To enable batch mode call begin() then perform as usually the necessary operations read and write and at the end call commit() to actually burn all written efuses. The batch mode can be used nested. The commit will be done by the last commit() function. The number of begin() functions should be equal to the number of commit() functions.

Note: If batch mode is enabled by the first task, at this time the second task cannot write/read efuses. The second task will wait for the first task to complete the batch operation.

// Example of using the batch writing mode.

// set the batch writing mode
esp_efuse_batch_write_begin();

// use any writing functions as usual
esp_efuse_write_field_blob(ESP_EFUSE_...);
esp_efuse_write_field_cnt(ESP_EFUSE_...);
esp_efuse_set_write_protect(EFUSE_BLKx);
esp_efuse_write_reg(EFUSE_BLKx, ...);
esp_efuse_write_block(EFUSE_BLKx, ...);
esp_efuse_write(ESP_EFUSE_1, 3);  // ESP_EFUSE_1 == 1, here we write a new value = 3. The changes will be burn by the commit() function.
esp_efuse_read_...(ESP_EFUSE_1);  // this function returns ESP_EFUSE_1 == 1 because uncommitted changes are not readable, it will be available only after commit.
...

// esp_efuse_batch_write APIs can be called recursively.
esp_efuse_batch_write_begin();
esp_efuse_set_write_protect(EFUSE_BLKx);
esp_efuse_batch_write_commit(); // the burn will be skipped here, it will be done in the last commit().

...

// Write all of these fields to the efuse registers
esp_efuse_batch_write_commit();
esp_efuse_read_...(ESP_EFUSE_1);  // this function returns ESP_EFUSE_1 == 3.

备注

Please note that reading in the batch mode does not show uncommitted changes.

返回:

  • ESP_OK: Successful.

esp_err_t esp_efuse_batch_write_cancel(void)

Reset the batch mode of writing fields.

It will reset the batch writing mode and any written changes.

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_STATE: The batch mode was not set.

esp_err_t esp_efuse_batch_write_commit(void)

Writes all prepared data for the batch mode.

Must be called to ensure changes are written to the efuse registers. After this the batch writing mode will be reset.

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_STATE: The deferred writing mode was not set.

  • ESP_FAIL: Failed to write efuse fields.

  • ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field.

bool esp_efuse_block_is_empty(esp_efuse_block_t block)

Checks that the given block is empty.

返回:

  • True: The block is empty.

  • False: The block is not empty or was an error.

bool esp_efuse_get_key_dis_read(esp_efuse_block_t block)

Returns a read protection for the key block.

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

True: The key block is read protected False: The key block is readable.

esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block)

Sets a read protection for the key block.

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

bool esp_efuse_get_key_dis_write(esp_efuse_block_t block)

Returns a write protection for the key block.

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

True: The key block is write protected False: The key block is writeable.

esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)

Sets a write protection for the key block.

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

  • ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field.

bool esp_efuse_key_block_unused(esp_efuse_block_t block)

Returns true if the key block is unused, false otherwise.

An unused key block is all zero content, not read or write protected, and has purpose 0 (ESP_EFUSE_KEY_PURPOSE_USER)

参数:

block -- key block to check.

返回:

  • True if key block is unused,

  • False if key block is used or the specified block index is not a key block.

bool esp_efuse_find_purpose(esp_efuse_purpose_t purpose, esp_efuse_block_t *block)

Find a key block with the particular purpose set.

参数:
  • purpose -- [in] Purpose to search for.

  • block -- [out] Pointer in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX which will be set to the key block if found. Can be NULL, if only need to test the key block exists.

返回:

  • True: If found,

  • False: If not found (value at block pointer is unchanged).

bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block)

Returns a write protection of the key purpose field for an efuse key block.

备注

For ESP32: no keypurpose, it returns always True.

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

True: The key purpose is write protected. False: The key purpose is writeable.

esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)

Returns the current purpose set for an efuse key block.

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

  • Value: If Successful, it returns the value of the purpose related to the given key block.

  • ESP_EFUSE_KEY_PURPOSE_MAX: Otherwise.

const esp_efuse_desc_t **esp_efuse_get_purpose_field(esp_efuse_block_t block)

Returns a pointer to a key purpose for an efuse key block.

To get the value of this field use esp_efuse_read_field_blob() or esp_efuse_get_key_purpose().

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

Pointer: If Successful returns a pointer to the corresponding efuse field otherwise NULL.

const esp_efuse_desc_t **esp_efuse_get_key(esp_efuse_block_t block)

Returns a pointer to a key block.

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

Pointer: If Successful returns a pointer to the corresponding efuse field otherwise NULL.

esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t purpose)

Sets a key purpose for an efuse key block.

参数:
  • block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

  • purpose -- [in] Key purpose.

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

esp_err_t esp_efuse_set_keypurpose_dis_write(esp_efuse_block_t block)

Sets a write protection of the key purpose field for an efuse key block.

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

  • ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field.

esp_efuse_block_t esp_efuse_find_unused_key_block(void)

Search for an unused key block and return the first one found.

See esp_efuse_key_block_unused for a description of an unused key block.

返回:

First unused key block, or EFUSE_BLK_KEY_MAX if no unused key block is found.

unsigned esp_efuse_count_unused_key_blocks(void)

Return the number of unused efuse key blocks in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX.

bool esp_efuse_get_digest_revoke(unsigned num_digest)

Returns the status of the Secure Boot public key digest revocation bit.

参数:

num_digest -- [in] The number of digest in range 0..2

返回:

  • True: If key digest is revoked,

  • False; If key digest is not revoked.

esp_err_t esp_efuse_set_digest_revoke(unsigned num_digest)

Sets the Secure Boot public key digest revocation bit.

参数:

num_digest -- [in] The number of digest in range 0..2

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

bool esp_efuse_get_write_protect_of_digest_revoke(unsigned num_digest)

Returns a write protection of the Secure Boot public key digest revocation bit.

参数:

num_digest -- [in] The number of digest in range 0..2

返回:

True: The revocation bit is write protected. False: The revocation bit is writeable.

esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest)

Sets a write protection of the Secure Boot public key digest revocation bit.

参数:

num_digest -- [in] The number of digest in range 0..2

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

  • ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field.

esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpose, const void *key, size_t key_size_bytes)

Program a block of key data to an efuse block.

The burn of a key, protection bits, and a purpose happens in batch mode.

备注

This API also enables the read protection efuse bit for certain key blocks like XTS-AES, HMAC, ECDSA etc. This ensures that the key is only accessible to hardware peripheral.

备注

For SoC's with capability SOC_EFUSE_ECDSA_USE_HARDWARE_K (e.g., ESP32-H2), this API writes an additional efuse bit for ECDSA key purpose to enforce hardware TRNG generated k mode in the peripheral.

参数:
  • block -- [in] Block to read purpose for. Must be in range EFUSE_BLK_KEY0 to EFUSE_BLK_KEY_MAX. Key block must be unused (esp_efuse_key_block_unused).

  • purpose -- [in] Purpose to set for this key. Purpose must be already unset.

  • key -- [in] Pointer to data to write.

  • key_size_bytes -- [in] Bytes length of data to write.

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_INVALID_STATE: Error in efuses state, unused block not found.

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

  • ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field.

esp_err_t esp_efuse_write_keys(const esp_efuse_purpose_t purposes[], uint8_t keys[][32], unsigned number_of_keys)

Program keys to unused efuse blocks.

The burn of keys, protection bits, and purposes happens in batch mode.

备注

This API also enables the read protection efuse bit for certain key blocks like XTS-AES, HMAC, ECDSA etc. This ensures that the key is only accessible to hardware peripheral.

备注

For SoC's with capability SOC_EFUSE_ECDSA_USE_HARDWARE_K (e.g., ESP32-H2), this API writes an additional efuse bit for ECDSA key purpose to enforce hardware TRNG generated k mode in the peripheral.

参数:
  • purposes -- [in] Array of purposes (purpose[number_of_keys]).

  • keys -- [in] Array of keys (uint8_t keys[number_of_keys][32]). Each key is 32 bytes long.

  • number_of_keys -- [in] The number of keys to write (up to 6 keys).

返回:

  • ESP_OK: Successful.

  • ESP_ERR_INVALID_ARG: Error in the passed arguments.

  • ESP_ERR_INVALID_STATE: Error in efuses state, unused block not found.

  • ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS: Error not enough unused key blocks available

  • ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.

  • ESP_ERR_CODING: Error range of data does not match the coding scheme.

  • ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field.

esp_err_t esp_secure_boot_read_key_digests(esp_secure_boot_key_digests_t *trusted_key_digests)

Read key digests from efuse. Any revoked/missing digests will be marked as NULL.

参数:

trusted_key_digests -- [out] Trusted keys digests, stored in this parameter after successfully completing this function. The number of digests depends on the SOC's capabilities.

返回:

  • ESP_OK: Successful.

  • ESP_FAIL: If trusted_keys is NULL or there is no valid digest.

esp_err_t esp_efuse_check_errors(void)

Checks eFuse errors in BLOCK0.

It does a BLOCK0 check if eFuse EFUSE_ERR_RST_ENABLE is set. If BLOCK0 has an error, it prints the error and returns ESP_FAIL, which should be treated as esp_restart.

备注

Refers to ESP32-C3 only.

返回:

  • ESP_OK: No errors in BLOCK0.

  • ESP_FAIL: Error in BLOCK0 requiring reboot.

esp_err_t esp_efuse_destroy_block(esp_efuse_block_t block)

Destroys the data in the given efuse block, if possible.

Data destruction occurs through the following steps: 1) Destroy data in the block:

  • If write protection is inactive for the block, then unset bits are burned.

  • If write protection is active, the block remains unaltered. 2) Set read protection for the block if possible (check write-protection for RD_DIS). In this case, data becomes inaccessible, and the software reads it as all zeros. If write protection is enabled and read protection can not be set, data in the block remains readable (returns an error).

Do not use the batch mode with this function as it does the burning itself!

参数:

block -- [in] A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX

返回:

  • ESP_OK: Successful.

  • ESP_FAIL: Data remained readable because the block is write-protected and read protection can not be set.

bool esp_efuse_is_flash_encryption_enabled(void)

Checks if flash encryption is enabled.

This function checks if the current eFuse configuration supports flash encryption.

bool esp_efuse_is_ecdsa_p192_curve_supported(void)

Checks if 192-bit ECDSA curve operations are supported.

This function checks if the current eFuse configuration supports 192-bit ECDSA curve operations.

bool esp_efuse_is_ecdsa_p256_curve_supported(void)

Checks if 256-bit ECDSA curve operations are supported.

This function checks if the current eFuse configuration supports 256-bit ECDSA curve operations.

esp_err_t esp_efuse_token_dump(esp_efuse_token_type_t dump_type, char *buf, size_t buf_len)

Print a single-line dump token that serializes all eFuse blocks.

Token formats (null-terminated strings):

  • Read efuse area EFSR:chip_name:chip_version:b64_blocks:b64_cerr:b64_crc32

  • Staged efuse area EFSW:chip_name:chip_version:b64_blocks:b64_cerr:b64_crc32

  • Combination of two areas (read and staged) EFSRW:...

This token is useful when a host tool cannot read the device directly (for example, when UART download mode is disabled, secure download is enabled). Copy the entire token string and decode it on a host that has access to espefuse.

Example (decode token and show only active fields):

espefuse --token EFSR:esp32:300:AAABAAAAAAAAAAAAAIAAAAAAAAAAABAAAAAAAA::oKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr8:::fPaC-A summary --active

Where:

  • token_marker = EFSR, EFSW, or EFSRW

  • chip_name = CONFIG_IDF_TARGET (e.g., "esp32c5")

  • chip_version = chip version (e.g., "100" for v1.0). version = major wafer version * 100 + minor wafer version.

  • b64_blocks = concatenation of all blocks’ 32-bit words (little-endian byte order), encoded as Base64URL without padding, for BLK0..BLK_MAX-1.

  • b64_cerr = optional coding-error snapshot.

  • b64_crc32 = crc32("token_marker:chip:ver:b64_blocks:b64_cerr:") b64 - base 64 format (Base64URL, UNPADDED)

备注

Dump modes that include staged data (ESP_EFUSE_TOKEN_FROM_STAGED and ESP_EFUSE_TOKEN_FROM_READ_STAGED) can expose sensitive data, including plaintext key material, because they show values before they are burned and before read-protection is applied. Treat EFSW/EFSRW tokens as sensitive artifacts and enable them only with CONFIG_EFUSE_ENABLE_STAGED_TOKEN_API.

备注

When buf is NULL, the token is printed with esp_log() using a non-constrained logging configuration. If the token must be emitted from a constrained environment, pass a buffer to this function and print or transport the resulting token with a constrained-safe method.

参数:
  • dump_type -- Select which efuse data to dump: read, staged writes, or both.

  • buf -- Buffer to store the resulting token string. If NULL, output goes to console.

  • buf_len -- Length of the buffer. Must be at least ESP_EFUSE_TOKEN_DUMP_MIN_LEN bytes to hold the full token for esp32xx series.

返回:

  • ESP_OK on success.

  • ESP_ERR_NOT_SUPPORTED if dump_type requests staged data and CONFIG_EFUSE_ENABLE_STAGED_TOKEN_API is disabled to avoid exposing staged values, including plaintext key material, before burn/read-protect.

  • ESP_ERR_INVALID_ARG if dump_type is invalid.

  • ESP_ERR_INVALID_SIZE if buf_len is too small

esp_err_t esp_efuse_token_burn(const char *token_in, bool ignore_ver)

Burns the EFSW token dump.

EFSW:chip_name:chip_version:b64_blocks::b64_crc32

The function validates:

  • Token marker EFSW

  • Chip name (must match CONFIG_IDF_TARGET)

  • Chip version is validated unless ignore_ver is set to true. The major version must be equal.

  • Chip version unless ignore_ver is true

  • CRC32

备注

The EFSW token dump can be produced from a host or from-device utility. Examples:

  • Host: espefuse burn-bit BLOCK2 1 --show-token

  • Device: esp_efuse_token_dump(ESP_EFUSE_TOKEN_FROM_STAGED, buf, len)

参数:
  • token_in -- Null-terminated EFSW token string.

  • ignore_ver -- If true, skip enforcing the wafer chip version in the token.

返回:

  • ESP_OK on success (token parsed and write efuse area is populated).

  • ESP_ERR_INVALID_ARG on format/mismatch errors (bad token marker/chip/ver/layout)

  • ESP_ERR_INVALID_CRC if CRC verification fails

  • ESP_ERR_INVALID_VERSION if chip version mismatches and ignore_ver is false

  • Other esp_err_t from lower layers if writing/burning fails

Structures

struct esp_efuse_desc_t

Type definition for an eFuse field.

Public Members

esp_efuse_block_t efuse_block

Block of eFuse

uint16_t bit_start

Start bit [0..511]

uint16_t bit_count

Length of bit field [1..-]

struct esp_secure_boot_key_digests_t

Pointers to the trusted key digests.

The number of digests depends on the SOC's capabilities.

Public Members

const void *key_digests[3]

Pointers to the key digests

Macros

ESP_ERR_EFUSE

Base error code for efuse api.

ESP_OK_EFUSE_CNT

OK the required number of bits is set.

ESP_ERR_EFUSE_CNT_IS_FULL

Error field is full.

ESP_ERR_EFUSE_REPEATED_PROG

Error repeated programming of programmed bits is strictly forbidden.

ESP_ERR_CODING

Error while a encoding operation.

ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS

Error not enough unused key blocks available

ESP_ERR_DAMAGED_READING

Error. Burn or reset was done during a reading operation leads to damage read data. This error is internal to the efuse component and not returned by any public API.

ESP_ERR_BURN_WR_DIS

Error to burn WR_DIS field.

ESP_EFUSE_MONITOR_EXECUTE_ESPEFUSE_SUMMARY

Flags specifying which source(s) to use when dumping eFUSE data.

Prefix used in device log lines to trigger automatic token decoding in idf.py monitor.

ESP_EFUSE_MONITOR_EXECUTE_ESPEFUSE_DUMP

Prefix used in device log lines to trigger token dump decoding in idf.py monitor.

ESP_EFUSE_TOKEN_DUMP_MIN_LEN

Recommended minimum buffer length for esp_efuse_token_dump().

Enumerations

enum esp_efuse_rom_log_scheme_t

Type definition for ROM log scheme.

Values:

enumerator ESP_EFUSE_ROM_LOG_ALWAYS_ON

Always enable ROM logging

enumerator ESP_EFUSE_ROM_LOG_ON_GPIO_LOW

ROM logging is enabled when specific GPIO level is low during start up

enumerator ESP_EFUSE_ROM_LOG_ON_GPIO_HIGH

ROM logging is enabled when specific GPIO level is high during start up

enumerator ESP_EFUSE_ROM_LOG_ALWAYS_OFF

Disable ROM logging permanently

enum esp_efuse_token_type_t

Values:

enumerator ESP_EFUSE_TOKEN_FROM_READ

Dump from the eFUSE read registers (the final, permanently programmed values).

enumerator ESP_EFUSE_TOKEN_FROM_STAGED

Dump from write/staging registers or programming buffer (pending or staged writes). This can expose keys in plaintext because it shows values that are not yet burned and not yet read-protected. Requires CONFIG_EFUSE_ENABLE_STAGED_TOKEN_API.

enumerator ESP_EFUSE_TOKEN_FROM_READ_STAGED

Combine both read and staged sources to show committed and pending values. The staged portion can expose keys in plaintext because it shows values that are not yet burned and not yet read-protected. Requires CONFIG_EFUSE_ENABLE_STAGED_TOKEN_API.


此文档对您有帮助吗?