mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-25 09:42:35 +00:00
efuse: Add support coding scheme to script
Added support using BLK1 and BLK2 in custom table. Added change size key in BLK1 and BLK2 if coding scheme was changed.
This commit is contained in:

committed by
bot

parent
693a5c209b
commit
9822055851
@@ -30,6 +30,16 @@ import ntpath
|
||||
__version__ = '1.0'
|
||||
|
||||
quiet = False
|
||||
coding_scheme = 0
|
||||
custom_table_use_BLK1 = False
|
||||
custom_table_use_BLK2 = False
|
||||
common_table_fix_size = False
|
||||
|
||||
CODE_SCHEME = {
|
||||
"NONE" : 0,
|
||||
"3/4" : 1,
|
||||
"REPEAT" : 2,
|
||||
}
|
||||
|
||||
copyright = '''// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
@@ -59,12 +69,11 @@ def critical(msg):
|
||||
class FuseTable(list):
|
||||
def __init__(self):
|
||||
super(FuseTable, self).__init__(self)
|
||||
self.md5_digest = ""
|
||||
self.md5_digest_table = ""
|
||||
|
||||
@classmethod
|
||||
def from_csv(cls, csv_contents):
|
||||
def from_csv(cls, csv_contents, type_table):
|
||||
res = FuseTable()
|
||||
res.md5_digest = res.calc_md5(csv_contents)
|
||||
lines = csv_contents.splitlines()
|
||||
def expand_vars(f):
|
||||
f = os.path.expandvars(f)
|
||||
@@ -120,6 +129,16 @@ class FuseTable(list):
|
||||
i_count = 0
|
||||
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
|
||||
res.calc_md5()
|
||||
|
||||
return res
|
||||
|
||||
def verify_duplicate_name(self):
|
||||
@@ -139,11 +158,9 @@ class FuseTable(list):
|
||||
if fl_error == True:
|
||||
raise InputError("Field names must be unique")
|
||||
|
||||
def verify(self):
|
||||
|
||||
'''list_field_names = []'''
|
||||
def verify(self, type_table = None):
|
||||
for p in self:
|
||||
p.verify()
|
||||
p.verify(type_table)
|
||||
|
||||
self.verify_duplicate_name()
|
||||
|
||||
@@ -156,8 +173,25 @@ class FuseTable(list):
|
||||
last.field_name, last.efuse_block, last.bit_start, last.bit_count))
|
||||
last = p
|
||||
|
||||
def calc_md5(self, csv_contents):
|
||||
return hashlib.md5(csv_contents).hexdigest()
|
||||
def fix_size_fields_from_blk1_blk2(self):
|
||||
for p in self:
|
||||
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()
|
||||
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))
|
||||
p.bit_count = max_bits
|
||||
|
||||
def keys_from_blk1_blk2_make_empty(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):
|
||||
p.bit_count = 0
|
||||
print("efuse: `%s` field was changed from %d to 0" %(p.field_name, p.bit_count))
|
||||
|
||||
def calc_md5(self):
|
||||
txt_table = ''
|
||||
for p in self:
|
||||
txt_table += "%s %s %d %d %s" % (p.field_name, p.efuse_block, p.bit_start, p.bit_count, p.comment) + "\n"
|
||||
self.md5_digest_table = hashlib.md5(txt_table).hexdigest()
|
||||
|
||||
def show_range_used_bits(self):
|
||||
# print used and free bits
|
||||
@@ -190,7 +224,7 @@ class FuseTable(list):
|
||||
"#endif",
|
||||
"",
|
||||
"",
|
||||
"// md5_digest " + self.md5_digest,
|
||||
"// md5_digest_table " + self.md5_digest_table,
|
||||
"// This file was generated automatically from the file " + file_name + ".csv. DO NOT CHANGE THIS FILE MANUALLY.",
|
||||
"// If you want to change some fields, you need to change " + file_name + ".csv file then build system will generate this header file",
|
||||
"// To show efuse_table run the command 'make show_efuse_table'.",
|
||||
@@ -215,7 +249,7 @@ class FuseTable(list):
|
||||
rows += [ '#include "esp_efuse.h"',
|
||||
'#include "' + file_name + '.h"',
|
||||
"",
|
||||
"// md5_digest " + self.md5_digest,
|
||||
"// md5_digest_table " + self.md5_digest_table,
|
||||
"// This file was generated automatically from the file " + file_name + ".csv. DO NOT CHANGE THIS FILE MANUALLY.",
|
||||
"// If you want to change some fields, you need to change " + file_name + ".csv file then build system will generate this header file",
|
||||
"// To show efuse_table run the command 'make show_efuse_table'.",
|
||||
@@ -293,18 +327,36 @@ class FuseDefinition(object):
|
||||
raise InputError("Field 'efuse_block' should consist from EFUSE_BLK0..EFUSE_BLK3")
|
||||
return strval
|
||||
|
||||
def verify(self):
|
||||
'''if self.field_name is None:
|
||||
raise ValidationError(self, "field_name field is not set")'''
|
||||
def get_max_bits_of_block(self):
|
||||
'''common_table: EFUSE_BLK0, EFUSE_BLK1, EFUSE_BLK2, EFUSE_BLK3
|
||||
custom_table: ----------, ----------, ----------, EFUSE_BLK3(some reserved in common_table)
|
||||
'''
|
||||
max_bits = 0
|
||||
if coding_scheme == CODE_SCHEME["NONE"] or self.efuse_block == "EFUSE_BLK0":
|
||||
max_bits = 256
|
||||
elif coding_scheme == CODE_SCHEME["3/4"]:
|
||||
max_bits = 192
|
||||
elif coding_scheme == CODE_SCHEME["REPEAT"]:
|
||||
max_bits = 128
|
||||
else:
|
||||
ValidationError(self, "Unknown coding scheme")
|
||||
return max_bits
|
||||
|
||||
def verify(self, type_table):
|
||||
if self.efuse_block is None:
|
||||
raise ValidationError(self, "efuse_block field is not set")
|
||||
if self.bit_count is None:
|
||||
raise ValidationError(self, "bit_count field is not set")
|
||||
|
||||
max_bits = 256
|
||||
if self.efuse_block == "EFUSE_BLK0":
|
||||
max_bits = 224
|
||||
if type_table is not None:
|
||||
if type_table == "custom_table":
|
||||
if self.efuse_block != "EFUSE_BLK3":
|
||||
ValidationError(self, "custom_table should use only EFUSE_BLK3")
|
||||
|
||||
max_bits = self.get_max_bits_of_block()
|
||||
|
||||
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 of the %s block" % (self.efuse_block))
|
||||
|
||||
def get_full_name(self):
|
||||
@@ -324,15 +376,26 @@ class FuseDefinition(object):
|
||||
str(self.bit_start),
|
||||
str(self.bit_count) + "}, \t // " + self.comment])
|
||||
|
||||
def process_input_file(file):
|
||||
def process_input_file(file, type_table):
|
||||
status("Parsing efuse CSV input file " + file.name + " ...")
|
||||
input = file.read()
|
||||
table = FuseTable.from_csv(input)
|
||||
|
||||
table = FuseTable.from_csv(input, type_table)
|
||||
status("Verifying efuse table...")
|
||||
table.verify()
|
||||
table.verify(type_table)
|
||||
return table
|
||||
|
||||
def ckeck_md5_in_file(md5, filename):
|
||||
if os.path.exists(filename):
|
||||
with open(filename,'r') as f:
|
||||
for line in f:
|
||||
if md5 in line:
|
||||
return True
|
||||
return False
|
||||
|
||||
def touch(fname, times=None):
|
||||
with open(fname, 'a'):
|
||||
os.utime(fname, times)
|
||||
|
||||
def create_output_files(name, output_table, debug):
|
||||
file_name = os.path.splitext(os.path.basename(name))[0]
|
||||
gen_dir = os.path.dirname(name)
|
||||
@@ -346,55 +409,74 @@ def create_output_files(name, output_table, debug):
|
||||
file_h_path = os.path.join(dir_for_file_h, file_name + ".h")
|
||||
file_c_path = os.path.join(gen_dir, file_name + ".c")
|
||||
|
||||
status("Creating efuse *.h file " + file_h_path + " ...")
|
||||
output = output_table.to_header(file_name)
|
||||
with open(file_h_path, 'w') as f:
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
status("Creating efuse *.c file " + file_c_path + " ...")
|
||||
output = output_table.to_c_file(file_name, debug)
|
||||
with open(file_c_path, 'w') as f:
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
# src files are the same
|
||||
if ckeck_md5_in_file(output_table.md5_digest_table, file_c_path) == False:
|
||||
status("Creating efuse *.h file " + file_h_path + " ...")
|
||||
output = output_table.to_header(file_name)
|
||||
with open(file_h_path, 'w') as f:
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
status("Creating efuse *.c file " + file_c_path + " ...")
|
||||
output = output_table.to_c_file(file_name, debug)
|
||||
with open(file_c_path, 'w') as f:
|
||||
f.write(output)
|
||||
f.close()
|
||||
else:
|
||||
print("touch: %s.c" % (file_name))
|
||||
touch(file_c_path)
|
||||
|
||||
def main():
|
||||
global quiet
|
||||
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.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('--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('--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('custom_input', help='Path to custom CSV file to parse.', type=argparse.FileType('rb'), nargs='?', default=None)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
coding_scheme = args.coding_scheme
|
||||
if CODE_SCHEME["NONE"] == coding_scheme:
|
||||
print("eFuse coding scheme: NONE")
|
||||
elif CODE_SCHEME["3/4"] == coding_scheme:
|
||||
print("eFuse coding scheme: 3/4")
|
||||
elif CODE_SCHEME["REPEAT"] == coding_scheme:
|
||||
print("eFuse coding scheme: REPEAT")
|
||||
|
||||
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
|
||||
debug = args.debug
|
||||
info = args.info
|
||||
|
||||
common_table = process_input_file(args.common_input)
|
||||
common_table = process_input_file(args.common_input, "common_table")
|
||||
two_table = common_table
|
||||
if args.custom_input is not None:
|
||||
custom_table = process_input_file(args.custom_input)
|
||||
common_table += custom_table
|
||||
common_table.verify()
|
||||
if info == True:
|
||||
output_table = common_table
|
||||
else:
|
||||
output_table = custom_table
|
||||
name = args.custom_input.name
|
||||
else:
|
||||
output_table = common_table
|
||||
name = args.common_input.name
|
||||
output_table.verify()
|
||||
custom_table = process_input_file(args.custom_input, "custom_table")
|
||||
two_table += custom_table
|
||||
two_table.verify()
|
||||
|
||||
# save files.
|
||||
if info == False:
|
||||
create_output_files(name, output_table, debug)
|
||||
if args.custom_input is None:
|
||||
create_output_files(args.common_input.name, common_table, debug)
|
||||
else:
|
||||
create_output_files(args.custom_input.name, custom_table, debug)
|
||||
else:
|
||||
print(output_table.show_range_used_bits())
|
||||
print(two_table.show_range_used_bits())
|
||||
|
||||
return 0
|
||||
|
||||
|
Reference in New Issue
Block a user