efuse: Fix make/cmake build systems and docs

This commit is contained in:
Konstantin Kondrashov
2018-12-06 17:49:02 +08:00
committed by bot
parent 9822055851
commit b8141f3ad8
12 changed files with 325 additions and 303 deletions

View File

@@ -18,43 +18,24 @@ register_component()
set(GEN_EFUSE_TABLE_ARG --coding_scheme ${CONFIG_EFUSE_CODE_SCHEME}) set(GEN_EFUSE_TABLE_ARG --coding_scheme ${CONFIG_EFUSE_CODE_SCHEME})
if(CONFIG_EFUSE_CUSTOM_TABLE_USE_BLK1)
list(APPEND GEN_EFUSE_TABLE_ARG --custom_table_use_BLK1)
endif()
if(CONFIG_EFUSE_CUSTOM_TABLE_USE_BLK2)
list(APPEND GEN_EFUSE_TABLE_ARG --custom_table_use_BLK2)
endif()
if(CONFIG_EFUSE_COMMON_TABLE_FIX_SIZE_BLK1_BLK2_DEP_ON_CODE_SCHEME)
list(APPEND GEN_EFUSE_TABLE_ARG --common_table_fix_size_secure_key_and_encrypt_key)
endif()
################### ###################
# Make common files esp_efuse_table.c and include/esp_efuse_table.h files. # Make common files esp_efuse_table.c and include/esp_efuse_table.h files.
set(EFUSE_COMMON_TABLE_CSV_PATH "${COMPONENT_PATH}/${SOC_NAME}/esp_efuse_table.csv") set(EFUSE_COMMON_TABLE_CSV_PATH "${COMPONENT_PATH}/${SOC_NAME}/esp_efuse_table.csv")
set(EFUSE_COMMON_TABLE_OUT_PATH "${COMPONENT_PATH}/${SOC_NAME}/esp_efuse_table.c")
add_custom_target(efuse_common_table COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/efuse_table_gen.py" ${EFUSE_COMMON_TABLE_CSV_PATH} ${GEN_EFUSE_TABLE_ARG})
################### ###################
# Make custom files project/main/esp_efuse_custom_table.c and project/main/include/esp_efuse_custom_table.h files. # Make custom files project/main/esp_efuse_custom_table.c and project/main/include/esp_efuse_custom_table.h files.
# Path to CSV file is relative to project path for custom CSV files. # Path to CSV file is relative to project path for custom CSV files.
if(${CONFIG_EFUSE_CUSTOM_TABLE}) if(${CONFIG_EFUSE_CUSTOM_TABLE})
# Custom filename expands any path relative to the project # Custom filename expands any path relative to the project
get_filename_component(EFUSE_CUSTOM_TABLE_CSV_PATH "${CONFIG_EFUSE_CUSTOM_TABLE_FILENAME}" ABSOLUTE BASE_DIR "${PROJECT_PATH}") get_filename_component(EFUSE_CUSTOM_TABLE_CSV_PATH "${CONFIG_EFUSE_CUSTOM_TABLE_FILENAME}" ABSOLUTE BASE_DIR "${IDF_PROJECT_PATH}")
string(REPLACE ".csv" ".c" EFUSE_CUSTOM_TABLE_OUT_PATH ${EFUSE_CUSTOM_TABLE_CSV_PATH}) add_custom_target(efuse_custom_table COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/efuse_table_gen.py" ${EFUSE_COMMON_TABLE_CSV_PATH} ${EFUSE_CUSTOM_TABLE_CSV_PATH} ${GEN_EFUSE_TABLE_ARG})
else()
add_custom_target(efuse_custom_table COMMAND)
endif()#if(${CONFIG_EFUSE_CUSTOM_TABLE}) endif()#if(${CONFIG_EFUSE_CUSTOM_TABLE})
set(GENERATED_SRC ${EFUSE_COMMON_TABLE_OUT_PATH} ${EFUSE_CUSTOM_TABLE_OUT_PATH}) add_custom_target(show_efuse_table COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/efuse_table_gen.py" ${EFUSE_COMMON_TABLE_CSV_PATH} ${EFUSE_CUSTOM_TABLE_CSV_PATH} ${GEN_EFUSE_TABLE_ARG} "--info")
set_source_files_properties(GENERATED_SRC PROPERTIES SYMBOLIC true)
add_custom_command(
OUTPUT GENERATED_OUTPUT
BYPRODUCTS ${GENERATED_SRC}
COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/efuse_table_gen.py"
${EFUSE_COMMON_TABLE_CSV_PATH} ${EFUSE_CUSTOM_TABLE_CSV_PATH} ${GEN_EFUSE_TABLE_ARG}
DEPENDS "${EFUSE_COMMON_TABLE_CSV_PATH}" "${EFUSE_CUSTOM_TABLE_CSV_PATH}" "${SDKCONFIG_CMAKE}"
VERBATIM)
add_custom_target(GENERATED_SRC DEPENDS GENERATED_OUTPUT ${GENERATED_SRC})
################### ###################
# Generates files for unit test. This command is run manually. # Generates files for unit test. This command is run manually.

View File

@@ -40,24 +40,4 @@ config EFUSE_CODE_SCHEME
default 1 if EFUSE_CODE_SCHEME_STATE_3_4 default 1 if EFUSE_CODE_SCHEME_STATE_3_4
default 2 if EFUSE_CODE_SCHEME_STATE_REPEAT default 2 if EFUSE_CODE_SCHEME_STATE_REPEAT
config EFUSE_CUSTOM_TABLE_USE_BLK1
bool "Use EFUSE_BLK1 for custom purpose"
default n
help
If this option is set then ENCRYPT_FLASH_KEY field from EFUSE_BLK1 [0..192/255] can not be used anymore.
ENCRYPT_FLASH_KEY field will contain 0 bits.
config EFUSE_CUSTOM_TABLE_USE_BLK2
bool "Use EFUSE_BLK2 for custom purpose"
default n
help
If this option is set then SECURE_BOOT_KEY field from EFUSE_BLK2 [0..192/255] can not be used anymore.
SECURE_BOOT_KEY field will contain 0 bits.
config EFUSE_COMMON_TABLE_FIX_SIZE_BLK1_BLK2_DEP_ON_CODE_SCHEME
bool "Limit size BLK1 and BLK2 if coding scheme is changed"
default y
help
efuse_table_gen.py tool will change size two fields: SECURE_BOOT_KEY and ENCRYPT_FLASH_KEY if they have not much coding scheme with a description in csv file.
endmenu endmenu

View File

@@ -1,57 +1,47 @@
# #
# eFuse Manager ganeretes header file. # eFuse Manager ganeretes header file.
# #
# .PHONY: efuse_table efuse_test_table show_efuse_table .PHONY: efuse_custom_table efuse_common_table efuse_test_table show_efuse_table
GEN_TOOL := $(COMPONENT_PATH)/efuse_table_gen.py GEN_EFUSE_TABLE := $(PYTHON) $(COMPONENT_PATH)/efuse_table_gen.py
GEN_EFUSE_TABLE := $(PYTHON) $(GEN_TOOL)
GEN_EFUSE_TABLE_ARG := --coding_scheme $(CONFIG_EFUSE_CODE_SCHEME) GEN_EFUSE_TABLE_ARG := --coding_scheme $(CONFIG_EFUSE_CODE_SCHEME)
ifdef CONFIG_EFUSE_CUSTOM_TABLE_USE_BLK1
GEN_EFUSE_TABLE_ARG += --custom_table_use_BLK1
endif
ifdef CONFIG_EFUSE_CUSTOM_TABLE_USE_BLK2
GEN_EFUSE_TABLE_ARG += --custom_table_use_BLK2
endif
ifdef CONFIG_EFUSE_COMMON_TABLE_FIX_SIZE_BLK1_BLK2_DEP_ON_CODE_SCHEME
GEN_EFUSE_TABLE_ARG += --common_table_fix_size_secure_key_and_encrypt_key
endif
################### ###################
# Make common files esp_efuse_table.c and include/esp_efuse_table.h files. # Make common files esp_efuse_table.c and include/esp_efuse_table.h files.
SOC_NAME := $(IDF_TARGET) SOC_NAME := $(IDF_TARGET)
EFUSE_COMMON_TABLE_CSV_PATH := $(COMPONENT_PATH)/$(SOC_NAME)/esp_efuse_table.csv EFUSE_COMMON_TABLE_CSV_PATH := $(COMPONENT_PATH)/$(SOC_NAME)/esp_efuse_table.csv
EFUSE_COMMON_TABLE_OUT_PATH := $(COMPONENT_PATH)/$(SOC_NAME)/esp_efuse_table.c
efuse_common_table:
@echo "COMMON_TABLE_CSV: $(EFUSE_COMMON_TABLE_CSV_PATH)"
$(GEN_EFUSE_TABLE) $(EFUSE_COMMON_TABLE_CSV_PATH) $(GEN_EFUSE_TABLE_ARG)
################### ###################
# Make custom files project/main/esp_efuse_custom_table.c and project/main/include/esp_efuse_custom_table.h files. # Make custom files project/main/esp_efuse_custom_table.c and project/main/include/esp_efuse_custom_table.h files.
ifdef CONFIG_EFUSE_CUSTOM_TABLE ifdef CONFIG_EFUSE_CUSTOM_TABLE
# Path to CSV file is relative to project path for custom CSV files. # Path to CSV file is relative to project path for custom CSV files.
EFUSE_CUSTOM_TABLE_CSV_PATH := $(call dequote,$(abspath $(call dequote, $(PROJECT_PATH))/$(call dequote,$(CONFIG_EFUSE_CUSTOM_TABLE_FILENAME)))) EFUSE_CUSTOM_TABLE_CSV_PATH := $(call dequote,$(abspath $(call dequote, $(PROJECT_PATH))/$(call dequote,$(CONFIG_EFUSE_CUSTOM_TABLE_FILENAME))))
EFUSE_CUSTOM_TABLE_OUT_PATH_CSV := $(call dequote,$(abspath $(call dequote, $(PROJECT_PATH))/$(call dequote,$(CONFIG_EFUSE_CUSTOM_TABLE_FILENAME))))
EFUSE_CUSTOM_TABLE_OUT_PATH := $(EFUSE_CUSTOM_TABLE_OUT_PATH_CSV:.csv=.c) efuse_custom_table:
@echo "COMMON_TABLE_CSV: $(EFUSE_COMMON_TABLE_CSV_PATH)"
@echo "CUSTOM_TABLE_CSV: $(EFUSE_CUSTOM_TABLE_CSV_PATH)"
$(GEN_EFUSE_TABLE) $(EFUSE_COMMON_TABLE_CSV_PATH) $(EFUSE_CUSTOM_TABLE_CSV_PATH) $(GEN_EFUSE_TABLE_ARG)
else else
efuse_custom_table:
EFUSE_CUSTOM_TABLE_CSV_PATH := EFUSE_CUSTOM_TABLE_CSV_PATH :=
EFUSE_CUSTOM_TABLE_OUT_PATH := EFUSE_CUSTOM_TABLE_OUT_PATH :=
endif # ifdef CONFIG_EFUSE_CUSTOM_TABLE endif # ifdef CONFIG_EFUSE_CUSTOM_TABLE
efuse_table: $(EFUSE_COMMON_TABLE_OUT_PATH) $(EFUSE_CUSTOM_TABLE_OUT_PATH)
$(EFUSE_COMMON_TABLE_OUT_PATH): $(EFUSE_COMMON_TABLE_CSV_PATH) $(SDKCONFIG_MAKEFILE)
@echo "COMMON_TABLE_CSV: $(EFUSE_COMMON_TABLE_CSV_PATH)"
$(GEN_EFUSE_TABLE) $(EFUSE_COMMON_TABLE_CSV_PATH) $(GEN_EFUSE_TABLE_ARG)
$(EFUSE_CUSTOM_TABLE_OUT_PATH): $(EFUSE_CUSTOM_TABLE_CSV_PATH) $(SDKCONFIG_MAKEFILE)
@echo "CUSTOM_TABLE_CSV: $(EFUSE_CUSTOM_TABLE_CSV_PATH)"
$(GEN_EFUSE_TABLE) $(EFUSE_COMMON_TABLE_CSV_PATH) $(EFUSE_CUSTOM_TABLE_CSV_PATH) $(GEN_EFUSE_TABLE_ARG)
###################
# print to console efuse table # print to console efuse table
show_efuse_table: show_efuse_table:
$(GEN_EFUSE_TABLE) $(EFUSE_COMMON_TABLE_CSV_PATH) $(EFUSE_CUSTOM_TABLE_CSV_PATH) $(GEN_EFUSE_TABLE_ARG) --info $(GEN_EFUSE_TABLE) $(EFUSE_COMMON_TABLE_CSV_PATH) $(EFUSE_CUSTOM_TABLE_CSV_PATH) $(GEN_EFUSE_TABLE_ARG) --info
################### ###################
# Generates files for unit test. This command is run manually. # Generates files for unit test. This command is run manually.
EFUSE_TEST_TABLE_CSV_PATH := $(COMPONENT_PATH)/test/esp_efuse_test_table.csv EFUSE_TEST_TABLE_CSV_PATH := $(COMPONENT_PATH)/test/esp_efuse_test_table.csv

View File

@@ -31,14 +31,11 @@ __version__ = '1.0'
quiet = False quiet = False
coding_scheme = 0 coding_scheme = 0
custom_table_use_BLK1 = False
custom_table_use_BLK2 = False
common_table_fix_size = False
CODE_SCHEME = { CODE_SCHEME = {
"NONE" : 0, "NONE" : 0,
"3/4" : 1, "3/4" : 1,
"REPEAT" : 2, "REPEAT" : 2,
} }
copyright = '''// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD copyright = '''// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
@@ -61,25 +58,27 @@ def status(msg):
if not quiet: if not quiet:
critical(msg) critical(msg)
def critical(msg): def critical(msg):
""" Print critical message to stderr """ """ Print critical message to stderr """
sys.stderr.write(msg) sys.stderr.write(msg)
sys.stderr.write('\n') sys.stderr.write('\n')
class FuseTable(list): class FuseTable(list):
def __init__(self): def __init__(self):
super(FuseTable, self).__init__(self) super(FuseTable, self).__init__(self)
self.md5_digest_table = "" self.md5_digest_table = ""
@classmethod @classmethod
def from_csv(cls, csv_contents, type_table): def from_csv(cls, csv_contents):
res = FuseTable() res = FuseTable()
lines = csv_contents.splitlines() lines = csv_contents.splitlines()
def expand_vars(f): def expand_vars(f):
f = os.path.expandvars(f) f = os.path.expandvars(f)
m = re.match(r'(?<!\\)\$([A-Za-z_][A-Za-z0-9_]*)', f) m = re.match(r'(?<!\\)\$([A-Za-z_][A-Za-z0-9_]*)', f)
if m: if m:
raise InputError("unknown variable '%s'" % m.group(1)) raise InputError("unknown variable '%s'" % (m.group(1)))
return f return f
for line_no in range(len(lines)): for line_no in range(len(lines)):
@@ -89,9 +88,9 @@ class FuseTable(list):
try: try:
res.append(FuseDefinition.from_csv(line)) res.append(FuseDefinition.from_csv(line))
except InputError as e: except InputError as e:
raise InputError("Error at line %d: %s" % (line_no+1, e)) raise InputError("Error at line %d: %s" % (line_no + 1, e))
except Exception: except Exception:
critical("Unexpected error parsing line %d: %s" % (line_no+1, line)) critical("Unexpected error parsing line %d: %s" % (line_no + 1, line))
raise raise
# fix up missing bit_start # fix up missing bit_start
@@ -111,14 +110,14 @@ class FuseTable(list):
last_field = None last_field = None
for e in res: for e in res:
if e.field_name == "" and last_field is None: if e.field_name == "" and last_field is None:
raise InputError("Error at line %d: %s missing field name" % (line_no+1, e)) raise InputError("Error at line %d: %s missing field name" % (line_no + 1, e))
elif e.field_name == "" and last_field is not None: elif e.field_name == "" and last_field is not None:
e.field_name = last_field.field_name e.field_name = last_field.field_name
last_field = e last_field = e
# fill group # fill group
names = [ p.field_name for p in res ] names = [p.field_name for p in res]
duplicates = set( n for n in names if names.count(n) > 1 ) duplicates = set(n for n in names if names.count(n) > 1)
if len(duplicates) != 0: if len(duplicates) != 0:
i_count = 0 i_count = 0
for p in res: for p in res:
@@ -129,13 +128,6 @@ class FuseTable(list):
i_count = 0 i_count = 0
res.verify_duplicate_name() res.verify_duplicate_name()
# fix size due to coding scheme
if type_table == "common_table":
if common_table_fix_size == True and (custom_table_use_BLK1 == False or custom_table_use_BLK2 == False):
res.fix_size_fields_from_blk1_blk2();
if custom_table_use_BLK1 == True or custom_table_use_BLK2 == True:
res.keys_from_blk1_blk2_make_empty();
# clac md5 for table # clac md5 for table
res.calc_md5() res.calc_md5()
@@ -143,8 +135,8 @@ class FuseTable(list):
def verify_duplicate_name(self): def verify_duplicate_name(self):
# check on duplicate name # check on duplicate name
names = [ p.field_name for p in self ] names = [p.field_name for p in self]
duplicates = set( n for n in names if names.count(n) > 1 ) duplicates = set(n for n in names if names.count(n) > 1)
# print sorted duplicate partitions by name # print sorted duplicate partitions by name
if len(duplicates) != 0: if len(duplicates) != 0:
@@ -153,8 +145,8 @@ class FuseTable(list):
field_name = p.field_name + p.group field_name = p.field_name + p.group
if field_name != "" and len(duplicates.intersection([field_name])) != 0: if field_name != "" and len(duplicates.intersection([field_name])) != 0:
fl_error = True fl_error = True
print ("Field at %s, %s, %s, %s have dublicate field_name" print ("Field at %s, %s, %s, %s have dublicate field_name" %
% ( p.field_name, p.efuse_block, p.bit_start, p.bit_count)) (p.field_name, p.efuse_block, p.bit_start, p.bit_count))
if fl_error == True: if fl_error == True:
raise InputError("Field names must be unique") raise InputError("Field names must be unique")
@@ -168,9 +160,9 @@ class FuseTable(list):
last = None last = None
for p in sorted(self, key=lambda x:(x.efuse_block, x.bit_start)): for p in sorted(self, key=lambda x:(x.efuse_block, x.bit_start)):
if last is not None and last.efuse_block == p.efuse_block and p.bit_start < last.bit_start + last.bit_count: if last is not None and last.efuse_block == p.efuse_block and p.bit_start < last.bit_start + last.bit_count:
raise InputError("Field at %s, %s, %s, %s overlaps %s, %s, %s, %s" raise InputError("Field at %s, %s, %s, %s overlaps %s, %s, %s, %s" %
% ( p.field_name, p.efuse_block, p.bit_start, p.bit_count, (p.field_name, p.efuse_block, p.bit_start, p.bit_count,
last.field_name, last.efuse_block, last.bit_start, last.bit_count)) last.field_name, last.efuse_block, last.bit_start, last.bit_count))
last = p last = p
def fix_size_fields_from_blk1_blk2(self): def fix_size_fields_from_blk1_blk2(self):
@@ -178,14 +170,14 @@ class FuseTable(list):
if (p.efuse_block == "EFUSE_BLK1" and custom_table_use_BLK1 == False) or (p.efuse_block == "EFUSE_BLK2" and custom_table_use_BLK2 == False): if (p.efuse_block == "EFUSE_BLK1" and custom_table_use_BLK1 == False) or (p.efuse_block == "EFUSE_BLK2" and custom_table_use_BLK2 == False):
max_bits = p.get_max_bits_of_block() max_bits = p.get_max_bits_of_block()
if p.bit_start == 0 and p.bit_count > max_bits: if p.bit_start == 0 and p.bit_count > max_bits:
print("Fix size `%s` field from %d to %d" %(p.field_name, p.bit_count, max_bits)) print("Fix size `%s` field from %d to %d" % (p.field_name, p.bit_count, max_bits))
p.bit_count = max_bits p.bit_count = max_bits
def keys_from_blk1_blk2_make_empty(self): def keys_from_blk1_blk2_make_empty(self):
for p in self: for p in self:
if (p.efuse_block == "EFUSE_BLK1" and custom_table_use_BLK1 == True) or (p.efuse_block == "EFUSE_BLK2" and custom_table_use_BLK2 == True): if (p.efuse_block == "EFUSE_BLK1" and custom_table_use_BLK1 == True) or (p.efuse_block == "EFUSE_BLK2" and custom_table_use_BLK2 == True):
p.bit_count = 0 p.bit_count = 0
print("efuse: `%s` field was changed from %d to 0" %(p.field_name, p.bit_count)) print("efuse: `%s` field was changed from %d to 0" % (p.field_name, p.bit_count))
def calc_md5(self): def calc_md5(self):
txt_table = '' txt_table = ''
@@ -198,8 +190,9 @@ class FuseTable(list):
rows = '' rows = ''
rows += 'Sorted efuse table:\n' rows += 'Sorted efuse table:\n'
num = 1 num = 1
rows = "{0} \t{1:<30} \t{2} \t{3} \t{4}".format("#", "field_name", "efuse_block", "bit_start", "bit_count") + "\n"
for p in sorted(self, key=lambda x:(x.efuse_block, x.bit_start)): for p in sorted(self, key=lambda x:(x.efuse_block, x.bit_start)):
rows += "#%d \t%s \t\t%s \t\t%d \t\t%d" % (num, p.field_name, p.efuse_block, p.bit_start, p.bit_count) + "\n" rows += "{0} \t{1:<30} \t{2} \t{3:^8} \t{4:^8}".format(num, p.field_name, p.efuse_block, p.bit_start, p.bit_count) + "\n"
num += 1 num += 1
rows += '\nUsed bits in efuse table:\n' rows += '\nUsed bits in efuse table:\n'
@@ -214,12 +207,12 @@ class FuseTable(list):
rows += '%d] [%d ' % (last.bit_start + last.bit_count - 1, p.bit_start) rows += '%d] [%d ' % (last.bit_start + last.bit_count - 1, p.bit_start)
last = p last = p
rows += '%d] \n' % (last.bit_start + last.bit_count - 1) rows += '%d] \n' % (last.bit_start + last.bit_count - 1)
rows += '\nNote: Not printed ranges are free for using.\n' rows += '\nNote: Not printed ranges are free for using. (bits in EFUSE_BLK0 are reserved for Espressif)\n'
return rows return rows
def to_header(self, file_name): def to_header(self, file_name):
rows = [ copyright ] rows = [copyright]
rows += [ "#ifdef __cplusplus", rows += ["#ifdef __cplusplus",
'extern "C" {', 'extern "C" {',
"#endif", "#endif",
"", "",
@@ -234,19 +227,19 @@ class FuseTable(list):
last_field_name = '' last_field_name = ''
for p in self: for p in self:
if (p.field_name != last_field_name): if (p.field_name != last_field_name):
rows += [ "extern const esp_efuse_desc_t* " + "ESP_EFUSE_" + p.field_name + "[];" ] rows += ["extern const esp_efuse_desc_t* " + "ESP_EFUSE_" + p.field_name + "[];"]
last_field_name = p.field_name last_field_name = p.field_name
rows += [ "", rows += ["",
"#ifdef __cplusplus", "#ifdef __cplusplus",
"}", "}",
"#endif", "#endif",
""] ""]
return '\n'.join(rows) + "\n" return '\n'.join(rows) + "\n"
def to_c_file(self, file_name, debug): def to_c_file(self, file_name, debug):
rows = [ copyright ] rows = [copyright]
rows += [ '#include "esp_efuse.h"', rows += ['#include "esp_efuse.h"',
'#include "' + file_name + '.h"', '#include "' + file_name + '.h"',
"", "",
"// md5_digest_table " + self.md5_digest_table, "// md5_digest_table " + self.md5_digest_table,
@@ -260,11 +253,11 @@ class FuseTable(list):
for p in self: for p in self:
if (p.field_name != last_name): if (p.field_name != last_name):
if last_name != '': if last_name != '':
rows += [ "};\n"] rows += ["};\n"]
rows += [ "static const esp_efuse_desc_t " + p.field_name + "[] = {" ] rows += ["static const esp_efuse_desc_t " + p.field_name + "[] = {"]
last_name = p.field_name last_name = p.field_name
rows += [ p.to_struct(debug) + "," ] rows += [p.to_struct(debug) + ","]
rows += [ "};\n" ] rows += ["};\n"]
rows += ["\n\n\n"] rows += ["\n\n\n"]
@@ -273,18 +266,18 @@ class FuseTable(list):
if (p.field_name != last_name): if (p.field_name != last_name):
if last_name != '': if last_name != '':
rows += [" NULL", rows += [" NULL",
"};\n" ] "};\n"]
rows += [ "const esp_efuse_desc_t* " + "ESP_EFUSE_" + p.field_name + "[] = {" ] rows += ["const esp_efuse_desc_t* " + "ESP_EFUSE_" + p.field_name + "[] = {"]
last_name = p.field_name last_name = p.field_name
index = str(0) if str(p.group) == "" else str(p.group) index = str(0) if str(p.group) == "" else str(p.group)
rows += [ " &" + p.field_name + "[" + index + "], \t\t// " + p.comment ] rows += [" &" + p.field_name + "[" + index + "], \t\t// " + p.comment]
rows += [" NULL", rows += [" NULL",
"};\n" ] "};\n" ]
return '\n'.join(rows) + "\n" return '\n'.join(rows) + "\n"
class FuseDefinition(object):
class FuseDefinition(object):
def __init__(self): def __init__(self):
self.field_name = "" self.field_name = ""
self.group = "" self.group = ""
@@ -297,7 +290,7 @@ class FuseDefinition(object):
def from_csv(cls, line): def from_csv(cls, line):
""" Parse a line from the CSV """ """ Parse a line from the CSV """
line_w_defaults = line + ",,,," # lazy way to support default fields line_w_defaults = line + ",,,," # lazy way to support default fields
fields = [ f.strip() for f in line_w_defaults.split(",") ] fields = [f.strip() for f in line_w_defaults.split(",")]
res = FuseDefinition() res = FuseDefinition()
res.field_name = fields[0] res.field_name = fields[0]
@@ -339,7 +332,7 @@ class FuseDefinition(object):
elif coding_scheme == CODE_SCHEME["REPEAT"]: elif coding_scheme == CODE_SCHEME["REPEAT"]:
max_bits = 128 max_bits = 128
else: else:
ValidationError(self, "Unknown coding scheme") raise ValidationError(self, "Unknown coding scheme")
return max_bits return max_bits
def verify(self, type_table): def verify(self, type_table):
@@ -351,13 +344,12 @@ class FuseDefinition(object):
if type_table is not None: if type_table is not None:
if type_table == "custom_table": if type_table == "custom_table":
if self.efuse_block != "EFUSE_BLK3": if self.efuse_block != "EFUSE_BLK3":
ValidationError(self, "custom_table should use only EFUSE_BLK3") raise ValidationError(self, "custom_table should use only EFUSE_BLK3")
max_bits = self.get_max_bits_of_block() max_bits = self.get_max_bits_of_block()
if self.bit_start + self.bit_count > max_bits: if self.bit_start + self.bit_count > max_bits:
print("(%d + %d) > %d" % (self.bit_start, self.bit_count, max_bits)) raise ValidationError(self, "The field is outside the boundaries(max_bits = %d) of the %s block" % (max_bits, self.efuse_block))
raise ValidationError(self, "The field is outside the boundaries of the %s block" % (self.efuse_block))
def get_full_name(self): def get_full_name(self):
def get_postfix(group): def get_postfix(group):
@@ -376,25 +368,24 @@ class FuseDefinition(object):
str(self.bit_start), str(self.bit_start),
str(self.bit_count) + "}, \t // " + self.comment]) str(self.bit_count) + "}, \t // " + self.comment])
def process_input_file(file, type_table): def process_input_file(file, type_table):
status("Parsing efuse CSV input file " + file.name + " ...") status("Parsing efuse CSV input file " + file.name + " ...")
input = file.read() input = file.read()
table = FuseTable.from_csv(input, type_table) table = FuseTable.from_csv(input)
status("Verifying efuse table...") status("Verifying efuse table...")
table.verify(type_table) table.verify(type_table)
return table return table
def ckeck_md5_in_file(md5, filename): def ckeck_md5_in_file(md5, filename):
if os.path.exists(filename): if os.path.exists(filename):
with open(filename,'r') as f: with open(filename, 'r') as f:
for line in f: for line in f:
if md5 in line: if md5 in line:
return True return True
return False return False
def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)
def create_output_files(name, output_table, debug): def create_output_files(name, output_table, debug):
file_name = os.path.splitext(os.path.basename(name))[0] file_name = os.path.splitext(os.path.basename(name))[0]
@@ -423,25 +414,19 @@ def create_output_files(name, output_table, debug):
f.write(output) f.write(output)
f.close() f.close()
else: else:
print("touch: %s.c" % (file_name)) print("Source files do not require updating correspond to csv file.")
touch(file_c_path)
def main(): def main():
global quiet global quiet
global coding_scheme global coding_scheme
global custom_table_use_BLK1
global custom_table_use_BLK2
global common_table_fix_size
parser = argparse.ArgumentParser(description='ESP32 eFuse Manager') parser = argparse.ArgumentParser(description='ESP32 eFuse Manager')
parser.add_argument('--quiet', '-q', help="Don't print non-critical status messages to stderr", action='store_true') parser.add_argument('--quiet', '-q', help="Don't print non-critical status messages to stderr", action='store_true')
parser.add_argument('--debug', help='Create header file with debug info', default=False, action="store_false") parser.add_argument('--debug', help='Create header file with debug info', default=False, action="store_false")
parser.add_argument('--info', help='Print info about range of used bits', default=False, action="store_true") parser.add_argument('--info', help='Print info about range of used bits', default=False, action="store_true")
parser.add_argument('--custom_table_use_BLK1', help='BLK1 is used for custom purpose', default=False, action="store_true") parser.add_argument('--coding_scheme', help='Coding scheme', type=int, default=0)
parser.add_argument('--custom_table_use_BLK2', help='BLK2 is used for custom purpose', default=False, action="store_true")
parser.add_argument('--common_table_fix_size_secure_key_and_encrypt_key', help='Size of secure_key and encrypt_key will limit to coding scheme', default=False, action="store_true")
parser.add_argument('--coding_scheme', help='Coding scheme', type=int, default=None)
parser.add_argument('common_input', help='Path to common CSV file to parse.', type=argparse.FileType('rb')) parser.add_argument('common_input', help='Path to common CSV file to parse.', type=argparse.FileType('rb'))
parser.add_argument('custom_input', help='Path to custom CSV file to parse.', type=argparse.FileType('rb'), nargs='?', default=None) parser.add_argument('custom_input', help='Path to custom CSV file to parse.', type=argparse.FileType('rb'), nargs='?', default=None)
@@ -454,10 +439,9 @@ def main():
print("eFuse coding scheme: 3/4") print("eFuse coding scheme: 3/4")
elif CODE_SCHEME["REPEAT"] == coding_scheme: elif CODE_SCHEME["REPEAT"] == coding_scheme:
print("eFuse coding scheme: REPEAT") print("eFuse coding scheme: REPEAT")
else:
raise InputError("unknown CODE_SCHEME = %s" % (coding_scheme))
custom_table_use_BLK1 = args.custom_table_use_BLK1
custom_table_use_BLK2 = args.custom_table_use_BLK2
common_table_fix_size = args.common_table_fix_size_secure_key_and_encrypt_key
quiet = args.quiet quiet = args.quiet
debug = args.debug debug = args.debug
info = args.info info = args.info
@@ -486,8 +470,7 @@ class InputError(RuntimeError):
class ValidationError(InputError): class ValidationError(InputError):
def __init__(self, p, message): def __init__(self, p, message):
super(ValidationError, self).__init__( super(ValidationError, self).__init__("Entry %s invalid: %s" % (p.field_name, message))
"Entry %s invalid: %s" % (p.field_name, message))
if __name__ == '__main__': if __name__ == '__main__':
try: try:

View File

@@ -161,10 +161,12 @@ uint32_t esp_efuse_read_reg(esp_efuse_block_t blk, unsigned int num_reg);
esp_err_t esp_efuse_write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint32_t val); esp_err_t esp_efuse_write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint32_t val);
/** /**
* @brief Return efuse coding_scheme for blocks. * @brief Return efuse coding scheme for blocks.
*
* Note: The coding scheme is applicable only to 1, 2 and 3 blocks. For 0 block, the coding scheme is always ``NONE``.
* *
* @param[in] blk Block number of eFuse. * @param[in] blk Block number of eFuse.
* @return Return efuse coding_scheme for blocks * @return Return efuse coding scheme for blocks
*/ */
esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk); esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk);

View File

@@ -15,7 +15,7 @@
#include "esp_efuse.h" #include "esp_efuse.h"
#include "esp_efuse_test_table.h" #include "esp_efuse_test_table.h"
// md5_digest dac4d84347dab29412b8b8713b4b0065 // md5_digest_table 7d587827a6f6134241dce7d3713b3edc
// This file was generated automatically from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // This file was generated automatically from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_test_table.csv file then build system will generate this header file // If you want to change some fields, you need to change esp_efuse_test_table.csv file then build system will generate this header file
// To show efuse_table run the command 'make show_efuse_table'. // To show efuse_table run the command 'make show_efuse_table'.

View File

@@ -17,7 +17,7 @@ extern "C" {
#endif #endif
// md5_digest dac4d84347dab29412b8b8713b4b0065 // md5_digest_table 7d587827a6f6134241dce7d3713b3edc
// This file was generated automatically from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // This file was generated automatically from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_test_table.csv file then build system will generate this header file // If you want to change some fields, you need to change esp_efuse_test_table.csv file then build system will generate this header file
// To show efuse_table run the command 'make show_efuse_table'. // To show efuse_table run the command 'make show_efuse_table'.

View File

@@ -8,8 +8,13 @@ import subprocess
import tempfile import tempfile
import os import os
import StringIO import StringIO
sys.path.append("..")
from efuse import * try:
import efuse_table_gen
except ImportError:
sys.path.append("..")
import efuse_table_gen
''' '''
To run the test on local PC: To run the test on local PC:
@@ -26,20 +31,20 @@ class CSVParserTests(unittest.TestCase):
name1, EFUSE_BLK3, 0, 5, Use for test name 1 name1, EFUSE_BLK3, 0, 5, Use for test name 1
name2, EFUSE_BLK3, 5, 4, Use for test name 2 name2, EFUSE_BLK3, 5, 4, Use for test name 2
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
t.verify() t.verify()
self.assertEqual(t[0].field_name, 'name1') self.assertEqual(t[0].field_name, 'name1')
self.assertEqual(t[0].efuse_block, 'EFUSE_BLK3') self.assertEqual(t[0].efuse_block, 'EFUSE_BLK3')
self.assertEqual(t[0].bit_start, 0) self.assertEqual(t[0].bit_start, 0)
self.assertEqual(t[0].bit_count, 5) self.assertEqual(t[0].bit_count, 5)
self.assertEqual(t[0].comment, 'Use for test name 1') self.assertEqual(t[0].comment, 'Use for test name 1')
self.assertEqual(t[1].field_name, 'name2') self.assertEqual(t[1].field_name, 'name2')
self.assertEqual(t[1].efuse_block, 'EFUSE_BLK3') self.assertEqual(t[1].efuse_block, 'EFUSE_BLK3')
self.assertEqual(t[1].bit_start, 5) self.assertEqual(t[1].bit_start, 5)
self.assertEqual(t[1].bit_count, 4) self.assertEqual(t[1].bit_count, 4)
self.assertEqual(t[1].comment, 'Use for test name 2') self.assertEqual(t[1].comment, 'Use for test name 2')
def test_seq_bit_start1_fill(self): def test_seq_bit_start1_fill(self):
csv = """ csv = """
@@ -47,16 +52,16 @@ name2, EFUSE_BLK3, 5,
name1, EFUSE_BLK3, , 5, name1, EFUSE_BLK3, , 5,
name2, EFUSE_BLK3, , 4, name2, EFUSE_BLK3, , 4,
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
t.verify() t.verify()
self.assertEqual(t[0].field_name, 'name1') self.assertEqual(t[0].field_name, 'name1')
self.assertEqual(t[0].bit_start, 0) self.assertEqual(t[0].bit_start, 0)
self.assertEqual(t[0].bit_count, 5) self.assertEqual(t[0].bit_count, 5)
self.assertEqual(t[1].field_name, 'name2') self.assertEqual(t[1].field_name, 'name2')
self.assertEqual(t[1].bit_start, 5) self.assertEqual(t[1].bit_start, 5)
self.assertEqual(t[1].bit_count, 4) self.assertEqual(t[1].bit_count, 4)
def test_seq_bit_start2_fill(self): def test_seq_bit_start2_fill(self):
csv = """ csv = """
@@ -64,16 +69,16 @@ name2, EFUSE_BLK3, ,
name1, EFUSE_BLK3, , 5, name1, EFUSE_BLK3, , 5,
name2, EFUSE_BLK2, , 4, name2, EFUSE_BLK2, , 4,
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
t.verify() t.verify()
self.assertEqual(t[0].field_name, 'name1') self.assertEqual(t[0].field_name, 'name1')
self.assertEqual(t[0].bit_start, 0) self.assertEqual(t[0].bit_start, 0)
self.assertEqual(t[0].bit_count, 5) self.assertEqual(t[0].bit_count, 5)
self.assertEqual(t[1].field_name, 'name2') self.assertEqual(t[1].field_name, 'name2')
self.assertEqual(t[1].bit_start, 0) self.assertEqual(t[1].bit_start, 0)
self.assertEqual(t[1].bit_count, 4) self.assertEqual(t[1].bit_count, 4)
def test_seq_bit_start3_fill(self): def test_seq_bit_start3_fill(self):
csv = """ csv = """
@@ -83,20 +88,20 @@ name2, EFUSE_BLK2, ,
name3, EFUSE_BLK2, 5, 4, name3, EFUSE_BLK2, 5, 4,
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
t.verify() t.verify()
self.assertEqual(t[0].field_name, 'name1') self.assertEqual(t[0].field_name, 'name1')
self.assertEqual(t[0].bit_start, 0) self.assertEqual(t[0].bit_start, 0)
self.assertEqual(t[0].bit_count, 5) self.assertEqual(t[0].bit_count, 5)
self.assertEqual(t[1].field_name, 'name2') self.assertEqual(t[1].field_name, 'name2')
self.assertEqual(t[1].bit_start, 0) self.assertEqual(t[1].bit_start, 0)
self.assertEqual(t[1].bit_count, 4) self.assertEqual(t[1].bit_count, 4)
self.assertEqual(t[2].field_name, 'name3') self.assertEqual(t[2].field_name, 'name3')
self.assertEqual(t[2].bit_start, 5) self.assertEqual(t[2].bit_start, 5)
self.assertEqual(t[2].bit_count, 4) self.assertEqual(t[2].bit_count, 4)
def test_seq_bit_start4_fill(self): def test_seq_bit_start4_fill(self):
csv = """ csv = """
@@ -106,9 +111,8 @@ name2, EFUSE_BLK2, ,
, EFUSE_BLK2, , 4, , EFUSE_BLK2, , 4,
name1, EFUSE_BLK3, , 5, name1, EFUSE_BLK3, , 5,
""" """
with self.assertRaisesRegexp(InputError, "Field names must be unique"): with self.assertRaisesRegexp(efuse_table_gen.InputError, "Field names must be unique"):
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
def test_seq_bit_start5_fill(self): def test_seq_bit_start5_fill(self):
csv = """ csv = """
@@ -118,24 +122,24 @@ name2, EFUSE_BLK2, ,
, EFUSE_BLK2, , 4, , EFUSE_BLK2, , 4,
name3, EFUSE_BLK3, 5, 5, name3, EFUSE_BLK3, 5, 5,
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
t.verify() t.verify()
self.assertEqual(t[0].field_name, 'name1') self.assertEqual(t[0].field_name, 'name1')
self.assertEqual(t[0].bit_start, 0) self.assertEqual(t[0].bit_start, 0)
self.assertEqual(t[0].bit_count, 5) self.assertEqual(t[0].bit_count, 5)
self.assertEqual(t[1].field_name, 'name2') self.assertEqual(t[1].field_name, 'name2')
self.assertEqual(t[1].bit_start, 0) self.assertEqual(t[1].bit_start, 0)
self.assertEqual(t[1].bit_count, 4) self.assertEqual(t[1].bit_count, 4)
self.assertEqual(t[2].field_name, 'name2') self.assertEqual(t[2].field_name, 'name2')
self.assertEqual(t[2].bit_start, 4) self.assertEqual(t[2].bit_start, 4)
self.assertEqual(t[2].bit_count, 4) self.assertEqual(t[2].bit_count, 4)
self.assertEqual(t[3].field_name, 'name3') self.assertEqual(t[3].field_name, 'name3')
self.assertEqual(t[3].bit_start, 5) self.assertEqual(t[3].bit_start, 5)
self.assertEqual(t[3].bit_count, 5) self.assertEqual(t[3].bit_count, 5)
def test_overlapping_bit_start_fail(self): def test_overlapping_bit_start_fail(self):
csv = """ csv = """
@@ -143,8 +147,8 @@ name3, EFUSE_BLK3, 5,
name1, EFUSE_BLK3, 1, 5, Use for test name 1 name1, EFUSE_BLK3, 1, 5, Use for test name 1
name2, EFUSE_BLK3, 5, 4, Use for test name 2 name2, EFUSE_BLK3, 5, 4, Use for test name 2
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
with self.assertRaisesRegexp(InputError, "overlap"): with self.assertRaisesRegexp(efuse_table_gen.InputError, "overlap"):
t.verify() t.verify()
def test_empty_field_name_fail(self): def test_empty_field_name_fail(self):
@@ -153,8 +157,8 @@ name2, EFUSE_BLK3, 5,
, EFUSE_BLK3, , 5, , EFUSE_BLK3, , 5,
name2, EFUSE_BLK2, , 4, name2, EFUSE_BLK2, , 4,
""" """
with self.assertRaisesRegexp(InputError, "missing field name"): with self.assertRaisesRegexp(efuse_table_gen.InputError, "missing field name"):
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
def test_unique_field_name_fail(self): def test_unique_field_name_fail(self):
csv = """ csv = """
@@ -162,8 +166,8 @@ name2, EFUSE_BLK2, ,
name1, EFUSE_BLK3, 0, 5, Use for test name 1 name1, EFUSE_BLK3, 0, 5, Use for test name 1
name1, EFUSE_BLK3, 5, 4, Use for test name 2 name1, EFUSE_BLK3, 5, 4, Use for test name 2
""" """
with self.assertRaisesRegexp(InputError, "Field names must be unique"): with self.assertRaisesRegexp(efuse_table_gen.InputError, "Field names must be unique"):
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
def test_bit_count_empty_fail(self): def test_bit_count_empty_fail(self):
csv = """ csv = """
@@ -171,8 +175,8 @@ name1, EFUSE_BLK3, 5,
name1, EFUSE_BLK3, 0, , Use for test name 1 name1, EFUSE_BLK3, 0, , Use for test name 1
name2, EFUSE_BLK3, 5, 4, Use for test name 2 name2, EFUSE_BLK3, 5, 4, Use for test name 2
""" """
with self.assertRaisesRegexp(InputError, "empty"): with self.assertRaisesRegexp(efuse_table_gen.InputError, "empty"):
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
def test_bit_start_num_fail(self): def test_bit_start_num_fail(self):
csv = """ csv = """
@@ -180,8 +184,8 @@ name2, EFUSE_BLK3, 5,
name1, EFUSE_BLK3, k, 5, Use for test name 1 name1, EFUSE_BLK3, k, 5, Use for test name 1
name2, EFUSE_BLK3, 5, 4, Use for test name 2 name2, EFUSE_BLK3, 5, 4, Use for test name 2
""" """
with self.assertRaisesRegexp(InputError, "Invalid field value"): with self.assertRaisesRegexp(efuse_table_gen.InputError, "Invalid field value"):
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
def test_join_entry(self): def test_join_entry(self):
csv = """ csv = """
@@ -192,33 +196,33 @@ name3, EFUSE_BLK3, 20,
, EFUSE_BLK3, 30, 5, Use for test name 3 , EFUSE_BLK3, 30, 5, Use for test name 3
name4, EFUSE_BLK2, 30, 5, Use for test name 4 name4, EFUSE_BLK2, 30, 5, Use for test name 4
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
t.verify() t.verify()
self.assertEqual(t[0].field_name, 'name1') self.assertEqual(t[0].field_name, 'name1')
self.assertEqual(t[0].efuse_block, 'EFUSE_BLK2') self.assertEqual(t[0].efuse_block, 'EFUSE_BLK2')
self.assertEqual(t[0].bit_start, 0) self.assertEqual(t[0].bit_start, 0)
self.assertEqual(t[0].bit_count, 6) self.assertEqual(t[0].bit_count, 6)
self.assertEqual(t[1].field_name, 'name2') self.assertEqual(t[1].field_name, 'name2')
self.assertEqual(t[1].efuse_block, 'EFUSE_BLK2') self.assertEqual(t[1].efuse_block, 'EFUSE_BLK2')
self.assertEqual(t[1].bit_start, 6) self.assertEqual(t[1].bit_start, 6)
self.assertEqual(t[1].bit_count, 5) self.assertEqual(t[1].bit_count, 5)
self.assertEqual(t[2].field_name, 'name3') self.assertEqual(t[2].field_name, 'name3')
self.assertEqual(t[2].efuse_block, 'EFUSE_BLK3') self.assertEqual(t[2].efuse_block, 'EFUSE_BLK3')
self.assertEqual(t[2].bit_start, 20) self.assertEqual(t[2].bit_start, 20)
self.assertEqual(t[2].bit_count, 5) self.assertEqual(t[2].bit_count, 5)
self.assertEqual(t[3].field_name, 'name3') self.assertEqual(t[3].field_name, 'name3')
self.assertEqual(t[3].efuse_block, 'EFUSE_BLK3') self.assertEqual(t[3].efuse_block, 'EFUSE_BLK3')
self.assertEqual(t[3].bit_start, 30) self.assertEqual(t[3].bit_start, 30)
self.assertEqual(t[3].bit_count, 5) self.assertEqual(t[3].bit_count, 5)
self.assertEqual(t[4].field_name, 'name4') self.assertEqual(t[4].field_name, 'name4')
self.assertEqual(t[4].efuse_block, 'EFUSE_BLK2') self.assertEqual(t[4].efuse_block, 'EFUSE_BLK2')
self.assertEqual(t[4].bit_start, 30) self.assertEqual(t[4].bit_start, 30)
self.assertEqual(t[4].bit_count, 5) self.assertEqual(t[4].bit_count, 5)
def test_block_fail(self): def test_block_fail(self):
csv = """ csv = """
@@ -226,8 +230,8 @@ name4, EFUSE_BLK2, 30,
name1, EFUSE_BLK5, 0, 5, Use for test name 1 name1, EFUSE_BLK5, 0, 5, Use for test name 1
name2, EFUSE_BLK3, 5, 4, Use for test name 2 name2, EFUSE_BLK3, 5, 4, Use for test name 2
""" """
with self.assertRaisesRegexp(InputError, "'efuse_block' should consist from EFUSE_BLK0..EFUSE_BLK3"): with self.assertRaisesRegexp(efuse_table_gen.InputError, "'efuse_block' should consist from EFUSE_BLK0..EFUSE_BLK3"):
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
def test_field_size_is_ok(self): def test_field_size_is_ok(self):
csv = """ csv = """
@@ -235,17 +239,19 @@ name2, EFUSE_BLK3, 5,
name1, EFUSE_BLK0, 0, 224, Use for test name 1 name1, EFUSE_BLK0, 0, 224, Use for test name 1
name2, EFUSE_BLK1, 0, 256, Use for test name 2 name2, EFUSE_BLK1, 0, 256, Use for test name 2
""" """
t = FuseTable.from_csv(csv) efuse_table_gen.coding_scheme = 0 # NONE
t = efuse_table_gen.FuseTable.from_csv(csv)
t.verify() t.verify()
def test_field_blk0_size_is_more(self): def test_field_blk3_size_is_more(self):
csv = """ csv = """
# field_name, efuse_block(EFUSE_BLK0..EFUSE_BLK3), bit_start(0..255), bit_count, comment # field_name, efuse_block(EFUSE_BLK0..EFUSE_BLK3), bit_start(0..255), bit_count, comment
name1, EFUSE_BLK0, 1, 224, Use for test name 1 name1, EFUSE_BLK3, 190, 1, Use for test name 1
name2, EFUSE_BLK1, 0, 256, Use for test name 2 name2, EFUSE_BLK3, 191, 5, Use for test name 2
""" """
t = FuseTable.from_csv(csv) efuse_table_gen.coding_scheme = 1 #3/4 coding
with self.assertRaisesRegexp(InputError, "The field is outside the boundaries"): t = efuse_table_gen.FuseTable.from_csv(csv)
with self.assertRaisesRegexp(efuse_table_gen.InputError, "The field is outside the boundaries"):
t.verify() t.verify()
def test_field_blk1_size_is_more(self): def test_field_blk1_size_is_more(self):
@@ -254,13 +260,14 @@ name2, EFUSE_BLK1, 0,
name1, EFUSE_BLK0, 0, 224, Use for test name 1 name1, EFUSE_BLK0, 0, 224, Use for test name 1
name2, EFUSE_BLK1, 1, 256, Use for test name 2 name2, EFUSE_BLK1, 1, 256, Use for test name 2
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
with self.assertRaisesRegexp(InputError, "The field is outside the boundaries"): with self.assertRaisesRegexp(efuse_table_gen.InputError, "The field is outside the boundaries"):
t.verify() t.verify()
class VerificationTests(unittest.TestCase): class VerificationTests(unittest.TestCase):
def test_bit_start_num_fail(self): def test_general(self):
csv = """ csv = """
# field_name, efuse_block(EFUSE_BLK0..EFUSE_BLK3), bit_start(0..255), bit_count, comment # field_name, efuse_block(EFUSE_BLK0..EFUSE_BLK3), bit_start(0..255), bit_count, comment
name1, EFUSE_BLK3, 0, 5, Use for test name 1 name1, EFUSE_BLK3, 0, 5, Use for test name 1
@@ -268,28 +275,60 @@ name2, EFUSE_BLK3, 5,
name1_1, EFUSE_BLK2, 0, 5, Use for test name 1_1 name1_1, EFUSE_BLK2, 0, 5, Use for test name 1_1
name2_1, EFUSE_BLK2, 5, 4, Use for test name 2_1 name2_1, EFUSE_BLK2, 5, 4, Use for test name 2_1
""" """
t = FuseTable.from_csv(csv) t = efuse_table_gen.FuseTable.from_csv(csv)
t.verify() t.verify()
self.assertEqual(t[0].field_name, 'name1') self.assertEqual(t[0].field_name, 'name1')
self.assertEqual(t[0].efuse_block, 'EFUSE_BLK3') self.assertEqual(t[0].efuse_block, 'EFUSE_BLK3')
self.assertEqual(t[0].bit_start, 0) self.assertEqual(t[0].bit_start, 0)
self.assertEqual(t[0].bit_count, 5) self.assertEqual(t[0].bit_count, 5)
self.assertEqual(t[1].field_name, 'name2') self.assertEqual(t[1].field_name, 'name2')
self.assertEqual(t[1].efuse_block, 'EFUSE_BLK3') self.assertEqual(t[1].efuse_block, 'EFUSE_BLK3')
self.assertEqual(t[1].bit_start, 5) self.assertEqual(t[1].bit_start, 5)
self.assertEqual(t[1].bit_count, 4) self.assertEqual(t[1].bit_count, 4)
self.assertEqual(t[2].field_name, 'name1_1') self.assertEqual(t[2].field_name, 'name1_1')
self.assertEqual(t[2].efuse_block, 'EFUSE_BLK2') self.assertEqual(t[2].efuse_block, 'EFUSE_BLK2')
self.assertEqual(t[2].bit_start, 0) self.assertEqual(t[2].bit_start, 0)
self.assertEqual(t[2].bit_count, 5) self.assertEqual(t[2].bit_count, 5)
self.assertEqual(t[3].field_name, 'name2_1') self.assertEqual(t[3].field_name, 'name2_1')
self.assertEqual(t[3].efuse_block, 'EFUSE_BLK2') self.assertEqual(t[3].efuse_block, 'EFUSE_BLK2')
self.assertEqual(t[3].bit_start, 5) self.assertEqual(t[3].bit_start, 5)
self.assertEqual(t[3].bit_count, 4) self.assertEqual(t[3].bit_count, 4)
if __name__ =="__main__": def test_custom_use_only_BLK3(self):
csv = """
# field_name, efuse_block(EFUSE_BLK0..EFUSE_BLK3), bit_start(0..255), bit_count, comment
name1, EFUSE_BLK3, 0, 5, Use for test name 1
name2, EFUSE_BLK2, 5, 4, Use for test name 2
"""
t = efuse_table_gen.FuseTable.from_csv(csv)
with self.assertRaisesRegexp(efuse_table_gen.ValidationError, "custom_table should use only EFUSE_BLK3"):
t.verify("custom_table")
def test_common_and_custom_table_use_the_same_bits(self):
csv_common = """
# field_name, efuse_block(EFUSE_BLK0..EFUSE_BLK3), bit_start(0..255), bit_count, comment
name1, EFUSE_BLK3, 0, 5, Use for test name 1
name2, EFUSE_BLK2, 5, 4, Use for test name 2
"""
common_table = efuse_table_gen.FuseTable.from_csv(csv_common)
common_table.verify("common_table")
two_tables = common_table
csv_custom = """
# field_name, efuse_block(EFUSE_BLK0..EFUSE_BLK3), bit_start(0..255), bit_count, comment
name3, EFUSE_BLK3, 20, 5, Use for test name 1
name4, EFUSE_BLK3, 4, 1, Use for test name 2
"""
custom_table = efuse_table_gen.FuseTable.from_csv(csv_custom)
custom_table.verify("custom_table")
two_tables += custom_table
with self.assertRaisesRegexp(efuse_table_gen.InputError, "overlaps"):
two_tables.verify()
if __name__ == "__main__":
unittest.main() unittest.main()

View File

@@ -13,4 +13,6 @@ list(APPEND COMPONENT_SRCS "src/memory_layout_utils.c")
set(COMPONENT_ADD_LDFRAGMENTS linker.lf) set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
set(COMPONENT_REQUIRES)
register_component() register_component()

View File

@@ -32,7 +32,7 @@ The component has API functions for reading and writing fields. Access to the fi
CSV files: CSV files:
* common (`esp_efuse_table.csv`) - contains efuse fields are used inside the IDF field. C-source generation should be done manually when changing this file (run command 'make efuse_common_table' or `idf.py efuse_common_table`). Note that changes to this file can lead to incorrect IDF operation. Changes are not desirable! * common (`esp_efuse_table.csv`) - contains efuse fields are used inside the IDF field. C-source generation should be done manually when changing this file (run command 'make efuse_common_table' or `idf.py efuse_common_table`). Note that changes to this file can lead to incorrect IDF operation. Changes are not desirable!
* custom - (may be absent, selected through :envvar:`CONFIG_EFUSE_CUSTOM_TABLE`) contains efuse fields that are used by the user in their application. C-source generation will be done automatically when changing this file. * custom - (may be absent, selected through :envvar:`CONFIG_EFUSE_CUSTOM_TABLE`) contains efuse fields that are used by the user in their application. C-source generation should be done manually when changing this file (run command 'make efuse_custom_table' or `idf.py efuse_custom_table`).
Description CSV file Description CSV file
@@ -49,7 +49,7 @@ Table header:
Individual params in csv file the following meanings: Individual params in csv file the following meanings:
field_name field_name
Name of field. The prefix `ESP_EFUSE_` will be added to the name, and this field name will be available in the code. This name will be used to access the fields. The name must be unique for all fields. If the line has an empty name, then this line is combined with the previous field. This allows you to set an arbitrary order of bits in the field, and expand the field as well. Name of field. The prefix `ESP_EFUSE_` will be added to the name, and this field name will be available in the code. This name will be used to access the fields. The name must be unique for all fields. If the line has an empty name, then this line is combined with the previous field. This allows you to set an arbitrary order of bits in the field, and expand the field as well (see ``MAC_FACTORY`` field in the common table).
efuse_block efuse_block
Block number. It determines where the efuse bits will be placed for this field. Available EFUSE_BLK0..EFUSE_BLK3. Block number. It determines where the efuse bits will be placed for this field. Available EFUSE_BLK0..EFUSE_BLK3.
@@ -88,6 +88,7 @@ To generate a `common` files, use the following command 'make efuse_common_table
:: ::
cd ~/esp/esp-idf/components/efuse/
./efuse_table_gen.py esp32/esp_efuse_table.csv ./efuse_table_gen.py esp32/esp_efuse_table.csv
After generation in the folder `esp32` create: After generation in the folder `esp32` create:
@@ -95,10 +96,11 @@ After generation in the folder `esp32` create:
* `esp_efuse_table.c` file. * `esp_efuse_table.c` file.
* In `include` folder `esp_efuse_table.c` file. * In `include` folder `esp_efuse_table.c` file.
To generate custom files, you need to build the project, the build system tracks changes in the csv file and starts the regeneration of the C-source files itself. In this case, the tool will be called with the following parameters: To generate a `custom` files, use the following command 'make efuse_custom_table' or `idf.py efuse_custom_table` or:
:: ::
cd ~/esp/esp-idf/components/efuse/
./efuse_table_gen.py esp32/esp_efuse_table.csv PROJECT_PATH/main/esp_efuse_custom_table.csv ./efuse_table_gen.py esp32/esp_efuse_table.csv PROJECT_PATH/main/esp_efuse_custom_table.csv
After generation in the folder PROJECT_PATH/main create: After generation in the folder PROJECT_PATH/main create:
@@ -113,6 +115,37 @@ To use the generated fields, you need to include two files:
#include "esp_efuse.h" #include "esp_efuse.h"
#include "esp_efuse_table.h" or "esp_efuse_custom_table.h" #include "esp_efuse_table.h" or "esp_efuse_custom_table.h"
Support coding scheme
---------------------
eFuse have three coding schemes:
* ``None`` (value 0).
* ``3/4`` (value 1).
* ``Repeat`` (value 2).
The coding scheme affects only EFUSE_BLK1, EFUSE_BLK2 and EFUSE_BLK3 blocks. EUSE_BLK0 block always has a coding scheme ``None``.
Coding changes the number of bits that can be written into a block, the block length is constant 256, some of these bits are used for encoding and are not used.
When using a coding scheme, the length of the payload that can be written is limited (for more detailes ``20.3.1.3 System Parameter coding_scheme``):
* None 256 bits.
* 3/4 192 bits.
* Repeat 128 bits.
You can find out the coding scheme of your chip:
* run a ``espefuse.py -p COM4 summary`` command.
* from ``esptool`` utility logs (during flashing).
* calling the function in the code :cpp:func:`esp_efuse_get_coding_scheme` for the EFUSE_BLK3 block.
eFuse tables must always comply with the coding scheme in the chip. There is an :envvar:`EFUSE_CODE_SCHEME_SELECTOR` option to select the coding type for tables in a Kconfig. When generating source files, if your tables do not follow the coding scheme, an error message will be displayed. Adjust the length or offset fields.
If your program was compiled with ``None`` encoding and ``3/4`` is used in the chip, then the ``ESP_ERR_CODING`` error may occur when calling the efuse API (the field is outside the block boundaries). If the field matches the new block boundaries, then the API will work without errors.
Also, 3/4 coding scheme imposes restrictions on writing bits belonging to one coding unit. The whole block with a length of 256 bits is divided into 4 coding units, and in each coding unit there are 6 bytes of useful data and 2 service bytes. These 2 service bytes contain the checksum of the previous 6 data bytes.
It turns out that only one field can be written into one coding unit. Repeated rewriting in one coding unit is prohibited. But if the record was made in advance or through a :cpp:func:`esp_efuse_write_block` function, then reading the fields belonging to one coding unit is possible.
eFuse API eFuse API
--------- ---------
@@ -124,6 +157,10 @@ Access to the fields is via a pointer to the description structure. API function
* :cpp:func:`esp_efuse_write_field_cnt` - writes a required count of bits as "1". * :cpp:func:`esp_efuse_write_field_cnt` - writes a required count of bits as "1".
* :cpp:func:`esp_efuse_get_field_size` - returns the number of bits by the field name. * :cpp:func:`esp_efuse_get_field_size` - returns the number of bits by the field name.
* :cpp:func:`esp_efuse_read_reg` - returns value of efuse register. * :cpp:func:`esp_efuse_read_reg` - returns value of efuse register.
* :cpp:func:`esp_efuse_write_reg` - writes value to efuse register.
* :cpp:func:`esp_efuse_get_coding_scheme` - returns efuse coding scheme for blocks.
* :cpp:func:`esp_efuse_read_block` - reads key to efuse block starting at the offset and the required size.
* :cpp:func:`esp_efuse_write_block` - writes key to efuse block starting at the offset and the required size.
For frequently used fields, special functions are made, like this :cpp:func:`esp_efuse_get_chip_ver`, :cpp:func:`esp_efuse_get_pkg_ver`. For frequently used fields, special functions are made, like this :cpp:func:`esp_efuse_get_chip_ver`, :cpp:func:`esp_efuse_get_pkg_ver`.
@@ -131,53 +168,55 @@ For frequently used fields, special functions are made, like this :cpp:func:`esp
How add a new field How add a new field
------------------- -------------------
1. Find a free bits for field. Show `efuse_table.csv` file or run the next command: 1. Find a free bits for field. Show `esp_efuse_table.csv` file or run ``make show_efuse_table`` or ``idf.py show_efuse_table`` or the next command:
:: ::
$ ./efuse_table_gen.py --info esp32/esp_efuse_table.csv $ ./efuse_table_gen.py --info esp32/esp_efuse_table.csv
Sorted efuse table: eFuse coding scheme: NONE
#1 WR_DIS_FLASH_CRYPT_CNT EFUSE_BLK0 2 1 # field_name efuse_block bit_start bit_count
#2 WR_DIS_BLK1 EFUSE_BLK0 7 1 1 WR_DIS_FLASH_CRYPT_CNT EFUSE_BLK0 2 1
#3 WR_DIS_BLK2 EFUSE_BLK0 8 1 2 WR_DIS_BLK1 EFUSE_BLK0 7 1
#4 WR_DIS_BLK3 EFUSE_BLK0 9 1 3 WR_DIS_BLK2 EFUSE_BLK0 8 1
#5 RD_DIS_BLK1 EFUSE_BLK0 16 1 4 WR_DIS_BLK3 EFUSE_BLK0 9 1
#6 RD_DIS_BLK2 EFUSE_BLK0 17 1 5 RD_DIS_BLK1 EFUSE_BLK0 16 1
#7 RD_DIS_BLK3 EFUSE_BLK0 18 1 6 RD_DIS_BLK2 EFUSE_BLK0 17 1
#8 FLASH_CRYPT_CNT EFUSE_BLK0 20 8 7 RD_DIS_BLK3 EFUSE_BLK0 18 1
#9 MAC_FACTORY EFUSE_BLK0 32 8 8 FLASH_CRYPT_CNT EFUSE_BLK0 20 8
#10 MAC_FACTORY EFUSE_BLK0 40 8 9 MAC_FACTORY EFUSE_BLK0 32 8
#11 MAC_FACTORY EFUSE_BLK0 48 8 10 MAC_FACTORY EFUSE_BLK0 40 8
#12 MAC_FACTORY EFUSE_BLK0 56 8 11 MAC_FACTORY EFUSE_BLK0 48 8
#13 MAC_FACTORY EFUSE_BLK0 64 8 12 MAC_FACTORY EFUSE_BLK0 56 8
#14 MAC_FACTORY EFUSE_BLK0 72 8 13 MAC_FACTORY EFUSE_BLK0 64 8
#15 MAC_FACTORY_CRC EFUSE_BLK0 80 8 14 MAC_FACTORY EFUSE_BLK0 72 8
#16 CHIP_VER_DIS_APP_CPU EFUSE_BLK0 96 1 15 MAC_FACTORY_CRC EFUSE_BLK0 80 8
#17 CHIP_VER_DIS_BT EFUSE_BLK0 97 1 16 CHIP_VER_DIS_APP_CPU EFUSE_BLK0 96 1
#18 CHIP_VER_PKG EFUSE_BLK0 105 3 17 CHIP_VER_DIS_BT EFUSE_BLK0 97 1
#19 CHIP_CPU_FREQ_LOW EFUSE_BLK0 108 1 18 CHIP_VER_PKG EFUSE_BLK0 105 3
#20 CHIP_CPU_FREQ_RATED EFUSE_BLK0 109 1 19 CHIP_CPU_FREQ_LOW EFUSE_BLK0 108 1
#21 CHIP_VER_REV1 EFUSE_BLK0 111 1 20 CHIP_CPU_FREQ_RATED EFUSE_BLK0 109 1
#22 ADC_VREF_AND_SDIO_DREF EFUSE_BLK0 136 6 21 CHIP_VER_REV1 EFUSE_BLK0 111 1
#23 XPD_SDIO_REG EFUSE_BLK0 142 1 22 ADC_VREF_AND_SDIO_DREF EFUSE_BLK0 136 6
#24 SDIO_TIEH EFUSE_BLK0 143 1 23 XPD_SDIO_REG EFUSE_BLK0 142 1
#25 SDIO_FORCE EFUSE_BLK0 144 1 24 SDIO_TIEH EFUSE_BLK0 143 1
#26 ENCRYPT_CONFIG EFUSE_BLK0 188 4 25 SDIO_FORCE EFUSE_BLK0 144 1
#27 CONSOLE_DEBUG_DISABLE EFUSE_BLK0 194 1 26 ENCRYPT_CONFIG EFUSE_BLK0 188 4
#28 ABS_DONE_0 EFUSE_BLK0 196 1 27 CONSOLE_DEBUG_DISABLE EFUSE_BLK0 194 1
#29 DISABLE_JTAG EFUSE_BLK0 198 1 28 ABS_DONE_0 EFUSE_BLK0 196 1
#30 DISABLE_DL_ENCRYPT EFUSE_BLK0 199 1 29 DISABLE_JTAG EFUSE_BLK0 198 1
#31 DISABLE_DL_DECRYPT EFUSE_BLK0 200 1 30 DISABLE_DL_ENCRYPT EFUSE_BLK0 199 1
#32 DISABLE_DL_CACHE EFUSE_BLK0 201 1 31 DISABLE_DL_DECRYPT EFUSE_BLK0 200 1
#33 ENCRYPT_FLASH_KEY EFUSE_BLK1 0 256 32 DISABLE_DL_CACHE EFUSE_BLK0 201 1
#34 SECURE_BOOT_KEY EFUSE_BLK2 0 256 33 ENCRYPT_FLASH_KEY EFUSE_BLK1 0 256
#35 MAC_CUSTOM_CRC EFUSE_BLK3 0 8 34 SECURE_BOOT_KEY EFUSE_BLK2 0 256
#36 MAC_CUSTOM EFUSE_BLK3 8 48 35 MAC_CUSTOM_CRC EFUSE_BLK3 0 8
#37 ADC1_TP_LOW EFUSE_BLK3 96 7 36 MAC_CUSTOM EFUSE_BLK3 8 48
#38 ADC1_TP_HIGH EFUSE_BLK3 103 9 37 ADC1_TP_LOW EFUSE_BLK3 96 7
#39 ADC2_TP_LOW EFUSE_BLK3 112 7 38 ADC1_TP_HIGH EFUSE_BLK3 103 9
#40 ADC2_TP_HIGH EFUSE_BLK3 119 9 39 ADC2_TP_LOW EFUSE_BLK3 112 7
#41 MAC_CUSTOM_VER EFUSE_BLK3 184 8 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: Used bits in efuse table:
EFUSE_BLK0 EFUSE_BLK0
@@ -190,18 +229,19 @@ How add a new field
[0 255] [0 255]
EFUSE_BLK3 EFUSE_BLK3
[0 55] [96 127] [184 191] [0 55] [96 159] [184 191]
Note: Not printed ranges are free for using. Note: Not printed ranges are free for using. (bits in EFUSE_BLK0 are reserved for Espressif)
Parsing efuse CSV input file esp32/esp_efuse_table.csv ... Parsing efuse CSV input file C:/msys32/home/virtpc/esp/esp-idf/components/efuse/esp32/esp_efuse_table.csv ...
Verifying efuse table... Verifying efuse table...
The number of bits not included in square brackets is free. All fields are checked for overlapping.
The number of bits not included in square brackets is free (bits in EFUSE_BLK0 are reserved for Espressif). All fields are checked for overlapping.
2. Fill a line for field: field_name, efuse_block, bit_start, bit_count, comment. 2. Fill a line for field: field_name, efuse_block, bit_start, bit_count, comment.
3. Run a command `make show_efuse_table` to check and generate header file. 3. Run a ``show_efuse_table`` command to check efuse table. To generate source files run ``efuse_common_table`` or ``efuse_custom_table`` command.
Debug efuse & Unit tests Debug efuse & Unit tests
------------------------ ------------------------
@@ -217,9 +257,9 @@ esptool have an useful tool for reading/writing ESP32 efuse bits - `espefuse.py
espefuse.py v2.3.1 espefuse.py v2.3.1
Connecting........_ Connecting........_
Security fuses: Security fuses:
FLASH_CRYPT_CNT Flash encryption mode counter = 0 R/W (0x4) FLASH_CRYPT_CNT Flash encryption mode counter = 0 R/W (0x0)
FLASH_CRYPT_CONFIG Flash encryption config (key tweak bits) = 0 R/W (0x0) FLASH_CRYPT_CONFIG Flash encryption config (key tweak bits) = 0 R/W (0x0)
CONSOLE_DEBUG_DISABLE Disable ROM BASIC interpreter fallback = 0 R/W (0x0) CONSOLE_DEBUG_DISABLE Disable ROM BASIC interpreter fallback = 1 R/W (0x1)
ABS_DONE_0 secure boot enabled for bootloader = 0 R/W (0x0) ABS_DONE_0 secure boot enabled for bootloader = 0 R/W (0x0)
ABS_DONE_1 secure boot abstract 1 locked = 0 R/W (0x0) ABS_DONE_1 secure boot abstract 1 locked = 0 R/W (0x0)
JTAG_DISABLE Disable JTAG = 0 R/W (0x0) JTAG_DISABLE Disable JTAG = 0 R/W (0x0)
@@ -231,12 +271,12 @@ esptool have an useful tool for reading/writing ESP32 efuse bits - `espefuse.py
BLK2 Secure boot key BLK2 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 = 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
BLK3 Variable Block 3 BLK3 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 = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa 87 02 91 00 00 00 00 00 00 00 00 00 00 00 00 R/W
Efuse fuses: Efuse fuses:
WR_DIS Efuse write disable mask = 0 R/W (0x0) WR_DIS Efuse write disable mask = 0 R/W (0x0)
RD_DIS Efuse read disablemask = 0 R/W (0x0) RD_DIS Efuse read disablemask = 0 R/W (0x0)
CODING_SCHEME Efuse variable block length scheme = 0 R/W (0x0) CODING_SCHEME Efuse variable block length scheme = 1 R/W (0x1) (3/4)
KEY_STATUS Usage of efuse block 3 (reserved) = 0 R/W (0x0) KEY_STATUS Usage of efuse block 3 (reserved) = 0 R/W (0x0)
Config fuses: Config fuses:
@@ -252,14 +292,18 @@ esptool have an useful tool for reading/writing ESP32 efuse bits - `espefuse.py
Identity fuses: Identity fuses:
MAC MAC Address MAC MAC Address
= 24:0a:c4:03:bb:68 (CRC 82 OK) R/W = 84:0d:8e:18:8e:44 (CRC ad OK) R/W
CHIP_VER_REV1 Silicon Revision 1 = 0 R/W (0x0) CHIP_VER_REV1 Silicon Revision 1 = 1 R/W (0x1)
CHIP_VERSION Reserved for future chip versions = 0 R/W (0x0) CHIP_VERSION Reserved for future chip versions = 2 R/W (0x2)
CHIP_PACKAGE Chip package identifier = 0 R/W (0x0) CHIP_PACKAGE Chip package identifier = 0 R/W (0x0)
Calibration fuses: Calibration fuses:
BLK3_PART_RESERVE BLOCK3 partially served for ADC calibration data = 0 R/W (0x0) BLK3_PART_RESERVE BLOCK3 partially served for ADC calibration data = 1 R/W (0x1)
ADC_VREF Voltage reference calibration = 1100 R/W (0x0) ADC_VREF Voltage reference calibration = 1114 R/W (0x2)
ADC1_TP_LOW ADC1 150mV reading = 346 R/W (0x11)
ADC1_TP_HIGH ADC1 850mV reading = 3285 R/W (0x5)
ADC2_TP_LOW ADC2 150mV reading = 449 R/W (0x7)
ADC2_TP_HIGH ADC2 850mV reading = 3362 R/W (0x1f5)
Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V). Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).

View File

@@ -13,7 +13,7 @@
.PHONY: build-components menuconfig defconfig all build clean all_binaries check-submodules size size-components size-files size-symbols list-components .PHONY: build-components menuconfig defconfig all build clean all_binaries check-submodules size size-components size-files size-symbols list-components
MAKECMDGOALS ?= all MAKECMDGOALS ?= all
all: efuse_table all_binaries | check_python_dependencies all: all_binaries | check_python_dependencies
# see below for recipe of 'all' target # see below for recipe of 'all' target
# #
# # other components will add dependencies to 'all_binaries'. The # # other components will add dependencies to 'all_binaries'. The
@@ -481,7 +481,7 @@ $(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp
$(summary) LD $(patsubst $(PWD)/%,%,$@) $(summary) LD $(patsubst $(PWD)/%,%,$@)
$(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP) $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP)
app: efuse_table $(APP_BIN) partition_table_get_info app: $(APP_BIN) partition_table_get_info
ifeq ("$(CONFIG_SECURE_BOOT_ENABLED)$(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)","y") # secure boot enabled, but remote sign app image ifeq ("$(CONFIG_SECURE_BOOT_ENABLED)$(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)","y") # secure boot enabled, but remote sign app image
@echo "App built but not signed. Signing step via espsecure.py:" @echo "App built but not signed. Signing step via espsecure.py:"
@echo "espsecure.py sign_data --keyfile KEYFILE $(APP_BIN)" @echo "espsecure.py sign_data --keyfile KEYFILE $(APP_BIN)"

View File

@@ -424,6 +424,7 @@ ACTIONS = {
"app-flash": (flash, ["app"], ["erase_flash"]), "app-flash": (flash, ["app"], ["erase_flash"]),
"efuse_common_table": (build_target, [], ["reconfigure"]), "efuse_common_table": (build_target, [], ["reconfigure"]),
"efuse_custom_table": (build_target, [], ["reconfigure"]), "efuse_custom_table": (build_target, [], ["reconfigure"]),
"show_efuse_table": (build_target, [], ["reconfigure"]),
"partition_table": (build_target, [], ["reconfigure"]), "partition_table": (build_target, [], ["reconfigure"]),
"partition_table-flash": (flash, ["partition_table"], ["erase_flash"]), "partition_table-flash": (flash, ["partition_table"], ["erase_flash"]),
"flash": (flash, ["all"], ["erase_flash"]), "flash": (flash, ["all"], ["erase_flash"]),