Skip to content
Permalink
bcafcf8fc3
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
114 lines (92 sloc) 3.72 KB
# Combine bootloader, partition table and application into a final binary.
import os, sys
sys.path.append(os.getenv("IDF_PATH") + "/components/partition_table")
import gen_esp32part
OFFSET_BOOTLOADER_DEFAULT = 0x1000
OFFSET_PARTITIONS_DEFAULT = 0x8000
def load_sdkconfig_value(filename, value, default):
value = "CONFIG_" + value + "="
with open(filename, "r") as f:
for line in f:
if line.startswith(value):
return line.split("=", 1)[1]
return default
def load_sdkconfig_hex_value(filename, value, default):
value = load_sdkconfig_value(filename, value, None)
if value is None:
return default
return int(value, 16)
def load_sdkconfig_str_value(filename, value, default):
value = load_sdkconfig_value(filename, value, None)
if value is None:
return default
return value.strip().strip('"')
def load_partition_table(filename):
with open(filename, "rb") as f:
return gen_esp32part.PartitionTable.from_binary(f.read())
# Extract command-line arguments.
arg_sdkconfig = sys.argv[1]
arg_bootloader_bin = sys.argv[2]
arg_partitions_bin = sys.argv[3]
arg_application_bin = sys.argv[4]
arg_output_bin = sys.argv[5]
arg_output_uf2 = sys.argv[6]
# Load required sdkconfig values.
idf_target = load_sdkconfig_str_value(arg_sdkconfig, "IDF_TARGET", "").upper()
offset_bootloader = load_sdkconfig_hex_value(
arg_sdkconfig, "BOOTLOADER_OFFSET_IN_FLASH", OFFSET_BOOTLOADER_DEFAULT
)
offset_partitions = load_sdkconfig_hex_value(
arg_sdkconfig, "PARTITION_TABLE_OFFSET", OFFSET_PARTITIONS_DEFAULT
)
# Load the partition table.
partition_table = load_partition_table(arg_partitions_bin)
max_size_bootloader = offset_partitions - offset_bootloader
max_size_partitions = 0
offset_application = 0
max_size_application = 0
# Inspect the partition table to find offsets and maximum sizes.
for part in partition_table:
if part.name == "nvs":
max_size_partitions = part.offset - offset_partitions
elif part.type == gen_esp32part.APP_TYPE and offset_application == 0:
offset_application = part.offset
max_size_application = part.size
# Define the input files, their location and maximum size.
files_in = [
("bootloader", offset_bootloader, max_size_bootloader, arg_bootloader_bin),
("partitions", offset_partitions, max_size_partitions, arg_partitions_bin),
("application", offset_application, max_size_application, arg_application_bin),
]
file_out = arg_output_bin
# Write output file with combined firmware.
cur_offset = offset_bootloader
with open(file_out, "wb") as fout:
for name, offset, max_size, file_in in files_in:
assert offset >= cur_offset
fout.write(b"\xff" * (offset - cur_offset))
cur_offset = offset
with open(file_in, "rb") as fin:
data = fin.read()
fout.write(data)
cur_offset += len(data)
print(
"%-12s@0x%06x % 8d (% 8d remaining)"
% (name, offset, len(data), max_size - len(data))
)
if len(data) > max_size:
print(
"ERROR: %s overflows allocated space of %d bytes by %d bytes"
% (name, max_size, len(data) - max_size)
)
sys.exit(1)
print("%-22s% 8d" % ("total", cur_offset))
# Generate .uf2 file if the SoC has native USB.
if idf_target in ("ESP32S2", "ESP32S3"):
sys.path.append(os.path.join(os.path.dirname(__file__), "../../tools"))
import uf2conv
families = uf2conv.load_families()
uf2conv.appstartaddr = 0
uf2conv.familyid = families[idf_target]
with open(arg_application_bin, "rb") as fin, open(arg_output_uf2, "wb") as fout:
fout.write(uf2conv.convert_to_uf2(fin.read()))