ESP32-S31 eFuse 表全解:使用 efuse_table_gen.py 查看字段布局与查找空闲位
2026/9/17 5:54:59 网站建设 项目流程

ESP32-S31 eFuse 表全解:使用 efuse_table_gen.py 查看字段布局与查找空闲位

【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf

本指南围绕 ESP-IDF 中 eFuse 系统 API 文档 的 "How to Add a New Field" 章节所引用的 ESP32-S31 eFuse 表输出文件(show-efuse-table_ESP32-S31.rst)展开,讲解如何通过idf.py show-efuse-table/efuse_table_gen.py --info查看 ESP32-S31 芯片全部 eFuse 字段的块分布、位偏移与位宽,并据此定位可用的空闲位,为自定义 eFuse 字段、安全配置(写保护、读保护、密钥管理等)提供依据。读完本文,你将能独立解读 eFuse 表输出、理解 EFUSE_BLK0~BLK9 的资源占用,并掌握从 CSV 表到 C 结构体的完整映射关系。

eFuse 表从哪来:一条命令看全芯片 eFuse 布局

在 ESP-IDF 中,每个芯片型号的 eFuse 字段都由一个 CSV 表定义(ESP32-S31 的表位于 components/efuse/esp32s31/esp_efuse_table.csv)。要查看这张表整理后的完整布局,官方文档提供了两种等价途径(见 efuse.rst 中 "How to Add a New Field" 一节):

  • 运行idf.py show-efuse-table
  • 直接运行底层工具:
$ ./efuse_table_gen.py -t {IDF_TARGET_PATH_NAME} {IDF_TARGET_PATH_NAME}/esp_efuse_table.csv --info

其中{IDF_TARGET_PATH_NAME}对于 ESP32-S31 即esp32s31,实际命令为:

$ ./efuse_table_gen.py -t esp32s31 esp32s31/esp_efuse_table.csv --info

--info是 efuse_table_gen.py 的一个命令行开关,其作用在源码中有明确注释:Print info about range of used bits。当指定该参数时,工具只打印字段布局信息而不生成任何 C 源文件;不指定时,它才会根据 CSV 生成esp_efuse_table.c/esp_efuse_table.h等代码文件。

输出开头还会打印Max number of bits in BLK 256,它来自工具默认的块长度max_blk_len = 256(每个 eFuse 块按 256 位计),该值可通过--max_blk_len参数调整,但只允许取256192128三个合法值,对应不同的编码方案可用位宽。

读懂输出第一段:Sorted efuse table 字段清单

命令输出的第一部分是排序后的字段明细表,列含义如下:

列名含义
#序号(按 efuse_block、bit_start 排序后的流水号)
field_nameeFuse 字段名,.表示父子层级关系
efuse_block字段所在的 eFuse 块(EFUSE_BLK0 ~ EFUSE_BLK9)
bit_start字段在该块内的起始位偏移(0 起)
bit_count字段位宽(占用的位数)

对 ESP32-S31,该表共列出 191 条字段记录。其中所有字段在块内按起始位从小到大排序,这一点可从源码实现确认:show_range_used_bits()使用sorted(self, key=lambda x: (x.efuse_block, x.bit_start))排序后逐条输出(见 efuse_table_gen.py 的 show_range_used_bits 实现)。

父子字段与位保护语义

字段名中的.表达继承关系。例如:

  • WR_DIS(EFUSE_BLK0,位 0~31)是父字段,代表"对单个 eFuse 的编程写保护开关";其下的WR_DIS.RD_DISWR_DIS.SECURE_BOOT_EN等是子字段,每一位对应一个受保护目标的写保护位。
  • RD_DIS(EFUSE_BLK0,位 32~38)是父字段,代表"禁止读取"控制,其子字段RD_DIS.BLOCK_KEY0~RD_DIS.BLOCK_KEY4分别控制 KEY0~KEY4 密钥块的读保护。
  • USER_DATA.MAC_CUSTOMUSER_DATA(EFUSE_BLK3)下的子字段,用于存放自定义 MAC(位 200 起,48 位)。
  • KEY0~KEY4各自独占一个 256 位块(EFUSE_BLK4~BLK8)。

这种父子关系在 efuse.rst 的 "Structured eFuse Fields" 一节 有详细说明:子字段必须落在父字段的位范围内,且子字段之间不允许位重叠(别名场景除外)。工具在解析 CSV 时会做重叠与越界检查,若违规会报错如Field at USER_DATA ... intersected with SERIAL_NUMBER ...

从 CSV 到 C 符号的映射

CSV 中定义的每个字段最终会生成对应的 C 结构指针符号。命名规则是:把字段名中的.全部替换为_,并加上ESP_EFUSE_前缀。例如:

  • WR_DIS.RD_DISESP_EFUSE_WR_DIS_RD_DIS
  • KEY0ESP_EFUSE_KEY0

这些符号声明在生成的头文件 components/efuse/esp32s31/include/esp_efuse_table.h 中,例如extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RD_DIS[];。该头文件顶部注释也明确提示:文件由 CSV 自动生成,不要手工修改;如需改动字段,应修改esp_efuse_table.csv后重新运行idf.py efuse-common-table

应用代码中使用这些字段时,只需包含两个头文件:

#include "esp_efuse.h" #include "esp_efuse_table.h" // 或自定义表 "esp_efuse_custom_table.h"

ESP32-S31 eFuse 块结构:BLK0~BLK9 全景

Sorted efuse table可以完整还原 ESP32-S31 的 10 个 eFuse 块(EFUSE_BLK0 ~ EFUSE_BLK9)的用途:

位宽主要字段典型用途
EFUSE_BLK0256WR_DIS、RD_DIS、安全/下载/JTAG 控制、密钥管理(KM)控制、RMA、防回滚等系统控制位(含 4 份硬件备份,可多次烧写)
EFUSE_BLK1256MAC、MAC_EXT、晶圆版本、BLK 版本、PSRAM 容量/厂商、封装版本、温度等级出厂校准与芯片标识(工厂预烧)
EFUSE_BLK2256OPTIONAL_UNIQUE_ID(128 位唯一 ID)可选的唯一标识
EFUSE_BLK3256USER_DATA、USER_DATA.MAC_CUSTOM用户数据 / 自定义 MAC
EFUSE_BLK4~BLK8256×5KEY0~KEY4安全密钥(可作闪存加密、安全启动密钥或用户数据)
EFUSE_BLK9256SYS_DATA_PART2、USB_DEVICE_EXCHG_PINS系统数据(预留)

BLK0:安全控制位最密集的块

BLK0 承载了几乎全部安全与启动控制位,按位偏移可归纳为几组:

  • 位 0~31 WR_DIS:写保护位,共 32 位,每个位锁定一个目标字段,例如WR_DIS.DIS_USB_JTAG(位 2)、WR_DIS.SECURE_BOOT_EN(位 15)、WR_DIS.BLOCK_KEY0~BLOCK_KEY4(位 23~27)、WR_DIS.SOFT_DIS_JTAG(位 31)。
  • 位 32~38 RD_DIS:读保护位,控制 KEY0~KEY4 块可否被读取。
  • 位 42~52 下载与 JTAG 控制DIS_USB_JTAG(42)、DIS_FORCE_DOWNLOAD(44)、SPI_DOWNLOAD_MSPI_DIS(45)、DIS_TWAI(46)、JTAG_SEL_ENABLE(47)、SOFT_DIS_JTAG(48,3 位)、DIS_PAD_JTAG(51)、DIS_DOWNLOAD_MANUAL_ENCRYPT(52)。
  • 位 55~82 密钥管理器(Key Manager)控制HUK_GEN_STATE(55,5 位)、KM_RND_SWITCH_CYCLE(64)、KM_DISABLE_DEPLOY_MODE(66,5 位)、KM_DEPLOY_ONLY_ONCE(71,5 位)、FORCE_USE_KEY_MANAGER_KEY(76,5 位)、FORCE_DISABLE_SW_INIT_KEY(81)、KM_XTS_KEY_LENGTH_256(82)。这些位控制硬件密钥管理器的部署模式、一次性部署、随机数切换周期以及 XTS 密钥长度(128/256 位)选择。
  • 位 83~131 加解密与安全启动WDT_DELAY_SEL(83)、DIS_SM_CRYPT(84,国密 SM2/SM3 禁用)、SPI_BOOT_CRYPT_CNT(85,3 位,闪存加密使能计数)、SECURE_BOOT_KEY_REVOKE0~2(88~90)、KEY_PURPOSE_0~4(96~120,各 5 位,描述各密钥用途)、ECC_FORCE_CONST_TIME(121)、ECDSA_DISABLE_SOFT_K(122)、SEC_DPA_LEVEL(123,2 位)、XTS_DPA_CLK_ENABLE(125)、XTS_DPA_PSEUDO_LEVEL(128,2 位)、SECURE_BOOT_EN(130)、SECURE_BOOT_AGGRESSIVE_REVOKE(131)。
  • 位 133~152 启动模式与打印控制FLASH_TYPE(133,NOR/NAND)、DIS_USB_OTG_DOWNLOAD_MODE(137)、FLASH_TPUW(140,4 位)、DIS_DOWNLOAD_MODE(144)、DIS_DIRECT_BOOT(145)、DIS_USB_SERIAL_JTAG_ROM_PRINT(146)、LOCK_KM_KEY(147)、DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE(148)、ENABLE_SECURITY_DOWNLOAD(149)、UART_PRINT_CONTROL(150,2 位)、FORCE_SEND_RESUME(152)。
  • 位 160~245 版本、回滚与物理安全SECURE_VERSION(160,16 位,ESP-IDF 防回滚版本号)、SECURE_BOOT_DISABLE_FAST_WAKE(176)、HYS_EN_PAD(177)、DCDC_VSET_EN(194)、DIS_WDT(195)、DIS_SWD(196)、SECURE_BOOT_SHA384_EN(203)、BOOTLOADER_ANTI_ROLLBACK_SECURE_VERSION(204,4 位)、BOOTLOADER_ANTI_ROLLBACK_EN(208)、BOOTLOADER_ANTI_ROLLBACK_UPDATE_IN_ROM(209)、RECOVERY_BOOTLOADER_FLASH_SECTOR(210,12 位)、RMA_ENA(222,2 位)、RMA_SESSION_COUNTER(224,3 位)、RMA_NONCE_ENA(227,2 位)、RMA_CHIP_INFO_SOURCE(229)、RMA_DISABLE_FAST_VEF(230)、PVT_0/1_GLITCH_EN(231/234)与_MODE(232/235,各 2 位)、PMU_FLASH_POWER_SEL(237)与_EN(238)、POWER_GLITCH_EN(239,4 位)、ENA_XTS_SHADOW(243)、ENA_SPI_BOOT_CRYPT_SCRAMBLER(244)、RE_ENABLE_JTAG_SOURCE(245)。

以上字段的完整注释(含义、取值与位语义)都维护在 esp_efuse_table.csv 中,例如SPI_BOOT_CRYPT_CNT注明{0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"}UART_PRINT_CONTROL注明四种取值对应的打印控制行为。

读懂输出第二段:Used bits in efuse table 与空闲位定位

命令输出的第二部分是每个块已被占用的位区间:

Used bits in efuse table: EFUSE_BLK0 [0 31] [0 1] [1 1] [1 1] ... [140 152] [160 177] [194 196] [203 245] EFUSE_BLK1 [0 63] [114 135] ... EFUSE_BLK9 [0 31] [192 192]

方括号[start end]表示一段连续被占用的位区间(含端点)。该区间的生成逻辑在源码 show_range_used_bits() 中:工具按(efuse_block, bit_start)排序后遍历所有字段,将相邻字段合并为连续区间——当上一个字段结束位与当前字段起始位不连续时(last.bit_start + last.bit_count != p.bit_start)就新开一个区间,直到块切换为止。

解读要点:

  • 方括号之外、未被任何区间覆盖的位就是空闲位,可用于新增自定义字段;
  • 输出末尾的备注明确指出:EFUSE_BLK0 中的空闲位为 Espressif 预留,用户自定义字段应优先考虑 EFUSE_BLK3(USER_DATA)等其他块;
  • 例如 EFUSE_BLK1 仅占用了[0 63](MAC 与 MAC_EXT,64 位)和[114 135](版本/PSRAM/封装信息区),中间[64 113]与末尾[136 255]的大段空间未占用;
  • EFUSE_BLK3 占用[0 255](USER_DATA 全块)及[200 247](MAC_CUSTOM 子字段区间,注意其与父字段区间重合属正常现象),其中 MAC_CUSTOM 之外的 USER_DATA 位可供自定义子字段使用,但新增子字段时必须遵循"落在父字段范围内且不与其他子字段重叠"的约束。

特别注意:字段重叠与越界检查由工具强制执行(efuse.rst 中给出的检查说明)。若新增字段与已有字段位重叠,会得到类似Field at USER_DATA, EFUSE_BLK3, 0, 256 intersected with SERIAL_NUMBER ...的错误,需把新字段改为已有字段的子字段(如USER_DATA.SERIAL_NUMBER);若子字段超出父字段范围,则报out of range错误,需调整bit_start使其落在父字段区间内。

在 ESP32-S31 上新增自定义 eFuse 字段的完整流程

结合 efuse.rst 的 "How to Add a New Field" 章节 与--info输出,可以总结出标准流程:

  1. 定位空闲位:运行idf.py show-efuse-table(或本文开头的efuse_table_gen.py --info命令),查看Used bits in efuse table中未被方括号覆盖的区间。
  2. 选择字段归属:若想挂到现有字段下,使用.操作符定义子字段,例如给USER_DATA添加SERIAL_NUMBERMODEL_NUMBERHARDWARE_REV
USER_DATA.SERIAL_NUMBER, EFUSE_BLK3, 0, 32, USER_DATA.MODEL_NUMBER, EFUSE_BLK3, 32, 10, USER_DATA.HARDWARE_REV, EFUSE_BLK3, 42, 10,
  1. 重新生成代码:系统字段修改 CSV 后运行idf.py efuse-common-table,自定义表运行idf.py efuse-custom-table;生成后重新编译工程。注意:efuse_table_gen.py在生成前还会校验字段名唯一性与位不重叠(见 工具说明)。
  2. 应用中使用:包含esp_efuse.h与对应表头文件,通过生成的ESP_EFUSE_<FIELD_NAME>符号调用esp_efuse_read_field_blob/esp_efuse_write_field_blob等 API 读写字段。

CSV 文件头部的注释也给出了同样的提醒(见 esp_efuse_table.csv 文件头):编辑文件后需手动运行idf.py efuse-common-table重新生成源文件并全量重新编译。

小结

  • efuse_table_gen.py -t esp32s31 esp32s31/esp_efuse_table.csv --info(或idf.py show-efuse-table)是查看 ESP32-S31 eFuse 资源布局的标准入口,输出Max number of bits in BLK、排序字段表与按块聚合的已用位区间三部分。
  • 字段表中的field_name.子字段层级结构、bit_start/bit_count与 C 符号ESP_EFUSE_*之间存在一一映射,映射源头是 esp_efuse_table.csv,生成产物是 esp_efuse_table.h。
  • Used bits中未出现在方括号内的位即空闲位,但EFUSE_BLK0 的空闲位归 Espressif 预留,自定义字段应避开,优先使用 USER_DATA 等块,并始终遵守工具强制执行的位重叠与越界检查规则。

【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询