Программирование ARM ESP32 eFuse Manager Thu, November 21 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


ESP32 eFuse Manager Печать
Добавил(а) microsin   

Библиотека eFuse Manager была разработана для структурирования доступа к битам eFuse [2], и для упрощения доступа к этим битам. Библиотека работает с битами eFuse по структурному имени, назначенном в таблице eFuse. В этой статье представлены некоторые концепции, используемые в eFuse Manager (перевод документации [1]).

На кристалле ESP32 имеется определенное количество так называемых бит eFuse, которые могут хранить в себе системные и пользовательские параметры. Каждый eFuse это однобитное поле, которое можно запрограммировать в 1, после чего его состояние обратно вернуть в 0 будет невозможно. Некоторые системные параметры используют эти биты eFuse напрямую в модулях аппаратуры, и находятся в специальных местах (например EFUSE_BLK0). Более подробно см. техническое руководство ESP32 Technical Reference Manual -> eFuse Controller (файл esp32_technical_reference_manual_en.pdf [5]). Также см. перевод описания контроллера eFuse из этого руководства [2].

Всего у ESP32 есть 4 блока eFuse, каждый размером 256 бит (но не все эти биты доступны):

EFUSE_BLK0: полностью используются в системных целях.
EFUSE_BLK1: используется для ключа шифрования flash. Если функция шифрования (Flash Encryption) не используется, то этот блок бит может использоваться для другой цели.
EFUSE_BLK2: используется для ключа технологии безопасной загрузки (security boot [3]). Если функция Secure Boot не используется, то этот блок может использоваться для другой цели.
EFUSE_BLK3: может частично использоваться для пользовательского MAC-адреса, или использоваться полностью для приложения пользователя. Обратите внимание, что некоторые биты уже используются в ESP IDF [4].

Каждый блок поделен на 8 регистров, каждый из 32 бит.

[Компонент eFuse Manager]

У компонента есть API-функции для чтения и записи полей бит. Доступ к этим полям осуществляется через структуры, которые описывают места размещения бит eFuse в блоках. Компонент предоставляет возможность формирования полей любой длины и любого количества отдельных бит. Описание полей сделано в файле CSV, в виде таблицы. Для генерации табличной формы (файл CSV) в исходном коде C используется скрипт efuse_table_gen.py. Этот скрипт проверяет файл CSV на уникальность имен полей и пересечение бит, в случае использования пользовательского файла из директории проекта пользователя, утилита проверит общий CSV-файл.

Файлы CSV:

common (общий файл esp_efuse_table.csv) - содержит поля eFuse, используемые средой разработки ESP IDF. Генерация исходного кода C должна быть сделана вручную, когда содержимое этого файла было изменено (путем запуска команды idf.py efuse-common-table). Обратите внимание, что изменения в этом файле могут привести к некорректному функционированию.

custom (использование этого файла необязательно, это можно разрешить опцией CONFIG_EFUSE_CUSTOM_TABLE) - содержит поля eFuse, которые используются пользователем в своем приложении. Генерация исходного кода C должна быть выполнена вручную, когда этот файл изменяется, путем запуска команды idf.py efuse-custom-table.

[Описание CSV-файла]

CSV-файл содержит описание полей eFuse. В простом случае одно поле имеет одну строку описания. Заголовок таблицы:

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

Отдельные параметры в CSV-файле означают следующее.

field_name: поле имени. К имени будет добавлен префикс ESP_EFUSE_, и это имя будет доступно в коде программы, его можно использовать для доступа к полям eFuse. Имена всех полей должны быть уникальными. Если строка содержит пустое имя, то эта строка будет комбинироваться с предыдущим полем. Это позволит Вам установить произвольный порядок бит в поле, а также расширить поле (см. поле MAC_FACTORY в таблице common). Поле field_name поддерживает структурный формат с использованием точки '.', чтобы показать, что поле принадлежит другому полю (см. WR_DIS и RD_DIS в таблице common).

efuse_block: номер блока. Определяет, где должны быть размещены биты для этого поля. Доступны номера блоков EFUSE_BLK0 .. EFUSE_BLK3.

bit_start: номер начального бита (0..255). Поле bit_start может быть опущено, тогда оно будет установлено на основании предыдущей записи, т. е. её bit_start + bit_count, если эта запись принадлежит тому же самому блоку efuse_block. Иначе, если efuse_block отличается, или это первая запись, будет сгенерирована ошибка.

bit_count: количество бит для использования в этом поле (1 .. n). Этот параметр обязателен, и не может быть опущен. Это поле также может быть значением MAX_BLK_LEN, тогда его длина будет равна максимальной длине блока, с учетом схемы кодирования (применимо для полей ключей шифрования ESP_EFUSE_SECURE_BOOT_KEY и ESP_EFUSE_ENCRYPT_FLASH_KEY). Значение MAX_BLK_LEN зависит от CONFIG_EFUSE_CODE_SCHEME_SELECTOR (опция выбора схемы кодирования): для None значение 256, для 3/4 значение 192, для REPEAT значение 128.

comment: комментарий, который также будет помещен в заголовочный файл C. Комментарий может быть опущен.

Если необходим не последовательный порядок следования бит для описания поля, то описание поля в следующих строка должно быть продолжено без указания имени field_name. Это покажет, что следующие записи будут принадлежать одному полю. Ниже показан пример двух полей MAC_FACTORY и 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

Это поле будет доступно в коде как ESP_EFUSE_MAC_FACTORY и ESP_EFUSE_MAC_FACTORY_CRC.

[Структурированные поля eFuse]

Структурированные поля выглядят наподобие WR_DIS.RD_DIS, где точка говорит от том, что поле принадлежит родительскому полю WR_DIS, и не может выйти за диапазон родительского поля.

WR_DIS,               EFUSE_BLK0, 0, 32, защита от записи ..
WR_DIS.RD_DIS,        EFUSE_BLK0, 0, 1,  .. для RD_DIS
WR_DIS.FIELD_1,       EFUSE_BLK0, 1, 1,  .. для FIELD_1
WR_DIS.FIELD_2,       EFUSE_BLK0, 2, 4,  .. для FIELD_2 (включает B1 и B2)
WR_DIS.FIELD_2.B1,    EFUSE_BLK0, 2, 2,  .. для FIELD_2.B1
WR_DIS.FIELD_2.B2,    EFUSE_BLK0, 4, 2,  .. для FIELD_2.B2
WR_DIS.FIELD_3,       EFUSE_BLK0, 5, 1,  .. для FIELD_3
WR_DIS.FIELD_3.ALIAS, EFUSE_BLK0, 5, 1,  .. для FIELD_3 (просто псевдоним WR_DIS.FIELD_3)
WR_DIS.FIELD_4,       EFUSE_BLK0, 7, 1,  .. для FIELD_4

Есть возможность использовать несколько уровней структурированных полей, как WR_DIS.FIELD_2.B1 и B2. Эти поля не должны пересекать друг друга, и их биты должны быть в пределах диапазонов двух полей WR_DIS и WR_DIS.FIELD_2.

Можно создавать псевдонимы для полей, находящихся в одном и том же диапазоне бит, см. WR_DIS.FIELD_3 и WR_DIS.FIELD_3.ALIAS.

Имена IDF для структурированных полей efuse должны быть уникальными. Утилита efuse_table_gen будет генерировать конечные имена, где точка будет заменена на символ подчеркивания '_'. Имена для использования в IDF: ESP_EFUSE_WR_DIS, ESP_EFUSE_WR_DIS_RD_DIS, ESP_EFUSE_WR_DIS_FIELD_2_B1, и т. д.

[Утилита efuse_table_gen.py]

Это скрипт на языке Python, который может генерировать исходный код на языке C из файла CSV, при этом будет сделана проверка его полей. Прежде всего производится проверка уникальности имен и наложение друг на друга полей бит. Если используется дополнительный пользовательский файл, то он будет проверен вместе с существующим общим файлом common (esp_efuse_table.csv). В случае ошибок отобразится сообщение и строка, которая привела к ошибке. Генерируемые файлы языка C будут содержать структуры типа esp_efuse_desc_t.

Для генерации файлов common используйте команду idf.py efuse-common-table, или:

cd $IDF_PATH/components/efuse/
./efuse_table_gen.py esp32/esp_efuse_table.csv

После завершения генерации в папке $IDF_PATH/components/efuse/esp32 будут созданы (или обновлены) файлы esp_efuse_table.c и include\esp_efuse_table.h.

Для генерации файлов пользователя custom используйте команду idf.py efuse-custom-table, или:

cd $IDF_PATH/components/efuse/
./efuse_table_gen.py esp32/esp_efuse_table.csv PROJECT_PATH/main/esp_efuse_custom_table.csv

После генерации в папке проекта PROJECT_PATH/main будет создан файл esp_efuse_custom_table.c, и в подкаталоге include будет создан заголовочный файл esp_efuse_custom_table.h.

Для использования сгенерированных полей в коде нужно будет подключить два файла:

#include "esp_efuse.h"
// В случае использования полей custom надо будет здесь подключить
// файл esp_efuse_custom_table.h вместо esp_efuse_table.h:
#include "esp_efuse_table.h"

[Поддерживаемые схемы кодирования]

eFuse использует 3 варианта схем кодирования, выбор схемы определяется значением опции CONFIG_EFUSE_CODE_SCHEME_SELECTOR:

None (значение 0).
3/4 (значение 1).
Repeat (значение 2).

Схема кодирования влияет только на блоки EFUSE_BLK1, EFUSE_BLK2 и EFUSE_BLK3. Блок EUSE_BLK0 всегда использует схему None. Схема кодирования меняет количество бит, которое можно записать в блок, длина блока постоянна и равна 256, некоторые их этих бит используются для кодирования, и они недоступны для пользователя.

Когда используется схема кодирования, длина полезной нагрузки ограничивается (подробнее см. раздел 20.3.1.3 System Parameter coding_scheme документа esp32_technical_reference_manual_en.pdf [5], или перевод [2]):

None: полезная нагрузка 256 бит.
3/4: полезная нагрузка 192 бит.
Repeat: полезная нагрузка 128 бит.

Используемую схему кодирования чипа можно определить следующими способами:

• Запуском команды espefuse.py -p PORT summary.
• Из логов утилиты esptool (после прошивки).
• Вызовом в коде функции esp_efuse_get_coding_scheme() для блока EFUSE_BLK3.

Используемую схему кодирования для библиотеки eFuse Manager в проекте можно поменять/проверить запуском команды idf.py menuconfig, после чего надо зайти в раздел настроек Component config -> eFuse Bit Manager -> Coding Scheme Compability:

menuconfig eFuse Manager coding scheme

Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
espefuse.py v3.2-dev
EFUSE_NAME (Block) Description  = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
BLK3_PART_RESERVE (BLOCK0):    BLOCK3 partially served for ADC calibration data   = False R/W (0b0)
ADC_VREF (BLOCK0):             Voltage reference calibration                      = 1128 R/W (0b00100)
 
Config fuses:
XPD_SDIO_FORCE (BLOCK0):       Ignore MTDI pin (GPIO12) for VDD_SDIO on reset     = False R/W (0b0)
XPD_SDIO_REG (BLOCK0):         If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset    = False R/W (0b0)
XPD_SDIO_TIEH (BLOCK0):        If XPD_SDIO_FORCE & XPD_SDIO_REG                   = 1.8V R/W (0b0)
CLK8M_FREQ (BLOCK0):           8MHz clock freq override                           = 49 R/W (0x31)
SPI_PAD_CONFIG_CLK (BLOCK0):   Override SD_CLK pad (GPIO6/SPICLK)                 = 0 R/W (0b00000)
SPI_PAD_CONFIG_Q (BLOCK0):     Override SD_DATA_0 pad (GPIO7/SPIQ)                = 0 R/W (0b00000)
SPI_PAD_CONFIG_D (BLOCK0):     Override SD_DATA_1 pad (GPIO8/SPID)                = 0 R/W (0b00000)
SPI_PAD_CONFIG_HD (BLOCK0):    Override SD_DATA_2 pad (GPIO9/SPIHD)               = 0 R/W (0b00000)
SPI_PAD_CONFIG_CS0 (BLOCK0):   Override SD_CMD pad (GPIO11/SPICS0)                = 0 R/W (0b00000)
DISABLE_SDIO_HOST (BLOCK0):    Disable SDIO host                                  = False R/W (0b0)
 
Efuse fuses:
WR_DIS (BLOCK0):               Efuse write disable mask                           = 0 R/W (0x0000)
RD_DIS (BLOCK0):               Efuse read disable mask                            = 0 R/W (0x0)
CODING_SCHEME (BLOCK0):        Efuse variable block length scheme
   = NONE (BLK1-3 len=256 bits) R/W (0b00)
KEY_STATUS (BLOCK0):           Usage of efuse block 3 (reserved)                  = False R/W (0b0)
 
Identity fuses:
MAC (BLOCK0):                  Factory MAC Address
   = 30:c6:f7:2a:3b:bc (CRC 0xc5 OK) R/W
MAC_CRC (BLOCK0):               CRC8 for factory MAC address                       = 197 R/W (0xc5)
CHIP_VER_REV1 (BLOCK0):         Silicon Revision 1                                 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0):         Silicon Revision 2                                 = True R/W (0b1)
CHIP_VERSION (BLOCK0):          Reserved for future chip versions                  = 2 R/W (0b10)
CHIP_PACKAGE (BLOCK0):          Chip package identifier                            = 0 R/W (0b000)
MAC_VERSION (BLOCK3):           Version of the MAC field                           = 0 R/W (0x00)
 
Security fuses:
FLASH_CRYPT_CNT (BLOCK0):       Flash encryption mode counter                      = 0 R/W (0b0000000)
UART_DOWNLOAD_DIS (BLOCK0):     Disable UART download mode (ESP32 rev3 only)       = False R/W (0b0)
FLASH_CRYPT_CONFIG (BLOCK0):    Flash encryption config (key tweak bits)           = 0 R/W (0x0)
CONSOLE_DEBUG_DISABLE (BLOCK0): Disable ROM BASIC interpreter fallback             = True R/W (0b1)
ABS_DONE_0 (BLOCK0):            Secure boot V1 is enabled for bootloader image     = False R/W (0b0)
ABS_DONE_1 (BLOCK0):            Secure boot V2 is enabled for bootloader image     = False R/W (0b0)
JTAG_DISABLE (BLOCK0):          Disable JTAG                                       = False R/W (0b0)
DISABLE_DL_ENCRYPT (BLOCK0):    Disable flash encryption in UART bootloader        = False R/W (0b0)
DISABLE_DL_DECRYPT (BLOCK0):    Disable flash decryption in UART bootloader        = False R/W (0b0)
DISABLE_DL_CACHE (BLOCK0):      Disable flash cache in UART bootloader             = False R/W (0b0)
BLOCK1 (BLOCK1):                Flash encryption key
   = 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
BLOCK2 (BLOCK2):                Secure boot key
   = 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
BLOCK3 (BLOCK3):                Variable Block 3
   = 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 voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).

Таблицы eFuse всегда должны соответствовать схеме кодирования в чипе. Существует опция для выбора кодирования CONFIG_EFUSE_CODE_SCHEME_SELECTOR в Kconfig. Когда генерируются файлы исходного кода, если Ваши таблицы не следуют схеме кодирования, то будет показано сообщение об ошибке. Настройте длину или смещение полей. Если Ваша программа была скомпилирована с кодированием None, и в чипе используется кодирование 3/4, то может произойти ошибка ESP_ERR_CODING, когда вызывается API (поле находится вне границ блока). Если поле соответствует новым границам блока, то API будет работать без ошибок.

Также схема кодирования 3/4 накладывает ограничения на запись бит, принадлежащих одному элементу кодирования. Весь блок длиной 256 делится на 4 элемента кодирования, и каждый элемент кодирования состоит из 6 байт с полезными данными и 2 сервисных байт. Эти 2 сервисных байта содержат контрольную сумму от предыдущих 6 байт данных. Получается, что в один элемент кодирования можно записать только одно поле. Повторяющиеся перезаписи одного и того же элемента кодирования запрещено. Однако если была сделана предварительная запись, или через функцию esp_efuse_write_block(), то возможно чтение полей, принадлежащих одному элементу кодирования.

В случае схемы кодирования 3/4 процесс записи делится на элементы кодирования, и мы не можем использовать обычный режим записи для некоторых полей. Мы можем подготовить все данные для записи, и прошить их за одну операцию. Вы также можете использовать этот режим и для схемы кодирования None, но для этого режима такой метод записи не является обязательным. Он важен для схемы 3/4. Пакетный режим записи блокирует операции esp_efuse_read_... (чтение eFuse).

После изменения схемы кодирования запустите команды efuse_common_table и efuse_custom_table, чтобы проверить таблицы новой схемы кодирования.

Чтобы записать некоторые поля в один блок, или разные блоки за одну операцию, необходимо использовать пакетный режим записи (batch writing mode). Сначала установите этот режим вызовом функции esp_efuse_batch_write_begin(), затем запишите некоторые поля как обычно, используя функции esp_efuse_write_... И в завершение прошейте их, для чего вызовите функцию esp_efuse_batch_write_commit(). Этот вызов прошьет подготовленные данные в блоки eFuse, и запретит batch recording mode.

Замечание: если в блоке eFuse уже есть записанные данные в схеме кодирования 3/4 или Repeat, то невозможно записать что-либо дополнительно (даже если требуемые биты пустые), без повреждения предыдущих закодированных данных. Эти данные кодирования будут полностью перезаписаны новыми данными кодирования, и полностью уничтожены (полезная нагрузка eFuse останется неповрежденной). Это может относиться к параметрам CUSTOM_MAC, SPI_PAD_CONFIG_HD, SPI_PAD_CONFIG_CS, и т. д. Пожалуйста, обратитесь к Espressif, чтобы закупить чипы/модули с требуемыми, предварительно записанными eFuse.

ТОЛЬКО ДЛЯ ТЕСТИРОВАНИЯ (НЕ РЕКОМЕНДУЕТСЯ): Вы можете игнорировать или подавить ошибки, которые нарушают схему кодирования данных, чтобы прошить необходимые биты в блок eFuse.

[eFuse API]

Заголовочный файл:

components/efuse/esp32/include/esp_efuse.h

Доступ к полям осуществляется через указатель на структуру описания. API-функции для выполнения базовых операций:

Функция Описание
esp_efuse_read_field_blob() Возвратит массив чтения бит eFuse.
esp_efuse_read_field_cnt() Возвратит количество бит, запрограммированных в 1.
esp_efuse_write_field_blob() Записывает массив.
esp_efuse_write_field_cnt() Записывает требуемое количество бит в 1.
esp_efuse_get_field_size() Возвратит количество бит по имени поля.
esp_efuse_read_reg() Возвратит значения регистра eFuse.
esp_efuse_write_reg() Записывает значение в регистр eFuse.
esp_efuse_get_coding_scheme() Возвратит схему кодирования для блоков eFuse.
esp_efuse_read_block() Возвратит ключ для блока eFuse, начиная с указанного смещения и требуемого размера.
esp_efuse_write_block() Запишет ключ для блока eFuse, начиная с указанного смещения и требуемого размера.
esp_efuse_batch_write_begin() Установит пакетный режим для записи полей.
esp_efuse_batch_write_commit() Запишет все подготовленные поля данных в пакетном режиме, и выполнит выход из пакетного режима записи.
esp_efuse_batch_write_cancel() Сбрасывает пакетный режим записи и подготовленные для этого данные.
esp_efuse_get_key_dis_read() Возвращает защиту от чтения для ключа блока.
esp_efuse_set_key_dis_read() Устанавливает защиту от чтения для ключа блока.
esp_efuse_get_key_dis_write() Возвратит защиту от записи для ключа блока.
esp_efuse_set_key_dis_write() Установит защиту от записи для ключа блока.
esp_efuse_get_key_purpose() Возвратит текущий набор предназначения для ключа блока.
esp_efuse_write_key() Программирует данные ключа в блок eFuse.
esp_efuse_write_keys() Программирует ключи для не используемых блоков eFuse.
esp_efuse_find_purpose() Найдет ключ блока с определенным набором предназначения.
esp_efuse_get_keypurpose_dis_write() Возвратит защиту от чтения поля предназначения ключа для ключа блока eFuse (для ESP32 всегда true).
esp_efuse_key_block_unused() Возвратит true, если ключ блока не используется, иначе false.

Для часто используемых полей сделаны специальные функции, наподобие esp_efuse_get_chip_ver(), esp_efuse_get_pkg_ver().

Подробное описание функций см. в документации [1].

[Как добавить новое поле]

1. Найдите свободные биты для поля. Для этого просмотрите файл esp_efuse_table.csv, или запустите команду idf.py show-efuse-table. Также можно запустить следующую команду:

$ ./efuse_table_gen.py esp32/esp_efuse_table.csv --info
eFuse coding scheme: NONE
#       field_name                      efuse_block     bit_start       bit_count
1       WR_DIS_FLASH_CRYPT_CNT          EFUSE_BLK0         2               1
2       WR_DIS_BLK1                     EFUSE_BLK0         7               1
3       WR_DIS_BLK2                     EFUSE_BLK0         8               1
4       WR_DIS_BLK3                     EFUSE_BLK0         9               1
5       RD_DIS_BLK1                     EFUSE_BLK0         16              1
6       RD_DIS_BLK2                     EFUSE_BLK0         17              1
7       RD_DIS_BLK3                     EFUSE_BLK0         18              1
8       FLASH_CRYPT_CNT                 EFUSE_BLK0         20              7
9       MAC_FACTORY                     EFUSE_BLK0         32              8
10      MAC_FACTORY                     EFUSE_BLK0         40              8
11      MAC_FACTORY                     EFUSE_BLK0         48              8
12      MAC_FACTORY                     EFUSE_BLK0         56              8
13      MAC_FACTORY                     EFUSE_BLK0         64              8
14      MAC_FACTORY                     EFUSE_BLK0         72              8
15      MAC_FACTORY_CRC                 EFUSE_BLK0         80              8
16      CHIP_VER_DIS_APP_CPU            EFUSE_BLK0         96              1
17      CHIP_VER_DIS_BT                 EFUSE_BLK0         97              1
18      CHIP_VER_PKG                    EFUSE_BLK0        105              3
19      CHIP_CPU_FREQ_LOW               EFUSE_BLK0        108              1
20      CHIP_CPU_FREQ_RATED             EFUSE_BLK0        109              1
21      CHIP_VER_REV1                   EFUSE_BLK0        111              1
22      ADC_VREF_AND_SDIO_DREF          EFUSE_BLK0        136              6
23      XPD_SDIO_REG                    EFUSE_BLK0        142              1
24      SDIO_TIEH                       EFUSE_BLK0        143              1
25      SDIO_FORCE                      EFUSE_BLK0        144              1
26      ENCRYPT_CONFIG                  EFUSE_BLK0        188              4
27      CONSOLE_DEBUG_DISABLE           EFUSE_BLK0        194              1
28      ABS_DONE_0                      EFUSE_BLK0        196              1
29      DISABLE_JTAG                    EFUSE_BLK0        198              1
30      DISABLE_DL_ENCRYPT              EFUSE_BLK0        199              1
31      DISABLE_DL_DECRYPT              EFUSE_BLK0        200              1
32      DISABLE_DL_CACHE                EFUSE_BLK0        201              1
33      ENCRYPT_FLASH_KEY               EFUSE_BLK1         0              256
34      SECURE_BOOT_KEY                 EFUSE_BLK2         0              256
35      MAC_CUSTOM_CRC                  EFUSE_BLK3         0               8
36      MAC_CUSTOM                      EFUSE_BLK3         8               48
37      ADC1_TP_LOW                     EFUSE_BLK3         96              7
38      ADC1_TP_HIGH                    EFUSE_BLK3        103              9
39      ADC2_TP_LOW                     EFUSE_BLK3        112              7
40      ADC2_TP_HIGH                    EFUSE_BLK3        119              9
41      SECURE_VERSION                  EFUSE_BLK3        128              32
42      MAC_CUSTOM_VER                  EFUSE_BLK3        184              8
 
Used bits in eFuse table:
EFUSE_BLK0
[2 2] [7 9] [16 18] [20 27] [32 87] [96 97] [105 109] [111 111] [136 144] [188 191]
 [194 194] [196 196] [198 201]
 
EFUSE_BLK1
[0 255]
 
EFUSE_BLK2
[0 255]
 
EFUSE_BLK3
[0 55] [96 159] [184 191]
 
Note: Not printed ranges are free for using. (bits in EFUSE_BLK0 are reserved for Espressif)
 
Parsing eFuse CSV input file $IDF_PATH/components/efuse/esp32/esp_efuse_table.csv ...
Verifying eFuse table...

Свободны биты, которые не попали в квадратные скобки (биты в блоке EFUSE_BLK0 зарезервированы для Espressif). Все поля проверяются на перекрытие друг на друга.

2. Заполните строку для нового поля: field_name, efuse_block, bit_start, bit_count, comment.

3. Запустите команду show_efuse_table, чтобы проверить таблицу eFuse. Чтобы сгенерировать файлы исходного кода запустите команду efuse_common_table или efuse_custom_table.

[Отладка eFuse и Unit-тесты]

Виртуальные eFuse. Опция CONFIG_EFUSE_VIRTUAL для Kconfig виртуализирует значения eFuse в среде eFuse Manager, так что записи эмулируются, и реальные значения eFuse не меняются. Это может быть полезно для отладки приложений и unit-тестов. Во время запуска приложения (startup), значения eFuse копируются в RAM. Все операции с eFuse (чтение и запись) выполняются с RAM вместо реальных регистров eFuse.

В дополнение к опции CONFIG_EFUSE_VIRTUAL option есть еще опция CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH, которая добавляет функцию сохранения значений eFuse в памяти flash. Для использования этого режима таблица разделов partition_table должна содержать раздел efuse. Файл partition.csv: "efuse_em, data, efuse,   ,   0x2000,". Во время startup, значения eFuse копируются из flash или, в случае когда flash пустая, из реальных eFuse в RAM, и затем обновляется flash. Эта опция позволяет сохранять значения eFuse между перезагрузками (с этой опцией можно проверить функции secure_boot и flash_encryption).

espefuse.py. Инструментарий esptool включает полезную утилиту для чтения/записи бит ESP32 eFuse - espefuse.py.

espefuse.py -p PORT summary
 
Connecting........__
Detecting chip type... ESP32
espefuse.py v3.1-dev
EFUSE_NAME (Block)  Description  = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
BLK3_PART_RESERVE (BLOCK0):     BLOCK3 partially served for ADC calibration data = True R/W (0b1)
ADC_VREF (BLOCK0):              Voltage reference calibration                    = 1114 R/W (0b00010)
ADC1_TP_LOW (BLOCK3):           ADC1 150mV reading                               = 346 R/W (0b0010001)
ADC1_TP_HIGH (BLOCK3):          ADC1 850mV reading                               = 3285 R/W (0b000000101)
ADC2_TP_LOW (BLOCK3):           ADC2 150mV reading                               = 449 R/W (0b0000111)
ADC2_TP_HIGH (BLOCK3):          ADC2 850mV reading                               = 3362 R/W (0b111110101)
 
Config fuses:
XPD_SDIO_FORCE (BLOCK0):        Ignore MTDI pin (GPIO12) for VDD_SDIO on reset   = False R/W (0b0)
XPD_SDIO_REG (BLOCK0):          If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset  = False R/W (0b0)
XPD_SDIO_TIEH (BLOCK0):         If XPD_SDIO_FORCE & XPD_SDIO_REG                 = 1.8V R/W (0b0)
CLK8M_FREQ (BLOCK0):            8MHz clock freq override                         = 53 R/W (0x35)
SPI_PAD_CONFIG_CLK (BLOCK0):    Override SD_CLK pad (GPIO6/SPICLK)               = 0 R/W (0b00000)
SPI_PAD_CONFIG_Q (BLOCK0):      Override SD_DATA_0 pad (GPIO7/SPIQ)              = 0 R/W (0b00000)
SPI_PAD_CONFIG_D (BLOCK0):      Override SD_DATA_1 pad (GPIO8/SPID)              = 0 R/W (0b00000)
SPI_PAD_CONFIG_HD (BLOCK0):     Override SD_DATA_2 pad (GPIO9/SPIHD)             = 0 R/W (0b00000)
SPI_PAD_CONFIG_CS0 (BLOCK0):    Override SD_CMD pad (GPIO11/SPICS0)              = 0 R/W (0b00000)
DISABLE_SDIO_HOST (BLOCK0):     Disable SDIO host                                = False R/W (0b0)
 
Efuse fuses:
WR_DIS (BLOCK0):                Efuse write disable mask                         = 0 R/W (0x0000)
RD_DIS (BLOCK0):                Efuse read disable mask                          = 0 R/W (0x0)
CODING_SCHEME (BLOCK0):         Efuse variable block length scheme
= 3/4 (BLK1-3 len=192 bits) R/W (0b01)
KEY_STATUS (BLOCK0):            Usage of efuse block 3 (reserved)                = False R/W (0b0)
 
Identity fuses:
MAC (BLOCK0):                   Factory MAC Address
= 84:0d:8e:18:8e:44 (CRC 0xad OK) R/W
MAC_CRC (BLOCK0):               CRC8 for factory MAC address                     = 173 R/W (0xad)
CHIP_VER_REV1 (BLOCK0):         Silicon Revision 1                               = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0):         Silicon Revision 2                               = False R/W (0b0)
CHIP_VERSION (BLOCK0):          Reserved for future chip versions                = 2 R/W (0b10)
CHIP_PACKAGE (BLOCK0):          Chip package identifier                          = 0 R/W (0b000)
MAC_VERSION (BLOCK3):           Version of the MAC field                         = 0 R/W (0x00)
 
Security fuses:
FLASH_CRYPT_CNT (BLOCK0):       Flash encryption mode counter                    = 0 R/W (0b0000000)
UART_DOWNLOAD_DIS (BLOCK0):     Disable UART download mode (ESP32 rev3 only)     = False R/W (0b0)
FLASH_CRYPT_CONFIG (BLOCK0):    Flash encryption config (key tweak bits)         = 0 R/W (0x0)
CONSOLE_DEBUG_DISABLE (BLOCK0): Disable ROM BASIC interpreter fallback           = True R/W (0b1)
ABS_DONE_0 (BLOCK0):            Secure boot V1 is enabled for bootloader image   = False R/W (0b0)
ABS_DONE_1 (BLOCK0):            Secure boot V2 is enabled for bootloader image   = False R/W (0b0)
JTAG_DISABLE (BLOCK0):          Disable JTAG                                     = False R/W (0b0)
DISABLE_DL_ENCRYPT (BLOCK0):    Disable flash encryption in UART bootloader      = False R/W (0b0)
DISABLE_DL_DECRYPT (BLOCK0):    Disable flash decryption in UART bootloader      = False R/W (0b0)
DISABLE_DL_CACHE (BLOCK0):      Disable flash cache in UART bootloader           = False R/W (0b0)
BLOCK1 (BLOCK1):                Flash encryption key
= 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
BLOCK2 (BLOCK2):                Secure boot key
= 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
BLOCK3 (BLOCK3):                Variable Block 3
= 00 00 00 00 00 00 00 00 00 00 00 00 91 02 87 fa 00 00 00 00 00 00 00 00 R/W
 
Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).

Для вывода дампа всех регистров eFuse:

espefuse.py -p PORT dump
 
Connecting........_
Detecting chip type... ESP32
BLOCK0 (                ) [0 ] read_regs: 00000000 8e188e44 00ad840d 0000e000 00000235 00000000 00000005
BLOCK1 (flash_encryption) [1 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK2 (secure_boot_v1 s) [2 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK3 (                ) [3 ] read_regs: 00000000 00000000 00000000 fa870291 00000000 00000000
espefuse.py v3.1-dev

[Ссылки]

1. ESP32 eFuse Manager site:docs.espressif.com.
2. ESP32: контроллер eFuse.
3. ESP32 Secure Boot V1.
4. Установка среды разработки ESP-IDF для ESP32.
5. ESP32 Technical Reference Manual site:docs.espressif.com.
6. ESP32: библиотека энергонезависимого хранилища данных.

 

Добавить комментарий


Защитный код
Обновить

Top of Page