You've already forked uiflow-micropython
mirror of
https://github.com/m5stack/uiflow-micropython.git
synced 2026-05-20 10:39:27 -07:00
5c8fac3142
Signed-off-by: tinyu <tinyu@m5stack.com>
226 lines
7.1 KiB
Python
226 lines
7.1 KiB
Python
# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
# Combine bootloader, partition table and application into a final binary.
|
|
|
|
from datetime import date
|
|
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
|
|
|
|
|
|
def load_sdkconfig_hex_value(filename, value, default):
|
|
value = "CONFIG_" + value + "="
|
|
with open(filename, "r") as f:
|
|
for line in f:
|
|
if line.startswith(value):
|
|
return int(line.split("=", 1)[1], 16)
|
|
return default
|
|
|
|
|
|
def load_sdkconfig_spiram_value(filename):
|
|
value = "SPIRAM_SUPPORT="
|
|
with open(filename, "r") as f:
|
|
for line in f:
|
|
if value in line:
|
|
if line.split("=", 1)[1][0] == "y":
|
|
return "SPIRAM-"
|
|
return ""
|
|
|
|
|
|
def load_sdkconfig_flash_size_value(filename):
|
|
value = "CONFIG_ESPTOOLPY_FLASHSIZE="
|
|
with open(filename, "r") as f:
|
|
for line in f:
|
|
if line.startswith(value):
|
|
return str(line.split("_")[-1].split("=", 1)[1][1:-2])
|
|
return "4MB"
|
|
|
|
|
|
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_nvs_bin = sys.argv[4]
|
|
arg_application_bin = sys.argv[5]
|
|
arg_fs_sys_bin = sys.argv[6]
|
|
arg_fs_vfs_bin = sys.argv[7]
|
|
arg_board_type_flag = sys.argv[8]
|
|
arg_lvgl_flag = sys.argv[9]
|
|
arg_output_bin = sys.argv[10]
|
|
arg_output_uf2 = sys.argv[11]
|
|
|
|
# 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_nvs = 0
|
|
max_size_nvs = 0
|
|
offset_application = 0
|
|
max_size_application = 0
|
|
offset_fs_sys = 0
|
|
max_size_fs_sys = 0
|
|
offset_fs_vfs = 0
|
|
max_size_fs_vfs = 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
|
|
offset_nvs = part.offset
|
|
max_size_nvs = part.size
|
|
elif part.type == gen_esp32part.APP_TYPE and offset_application == 0:
|
|
offset_application = part.offset
|
|
max_size_application = part.size
|
|
elif part.type == gen_esp32part.DATA_TYPE and part.name == "sys":
|
|
offset_fs_sys = part.offset
|
|
max_size_fs_sys = part.size
|
|
elif part.type == gen_esp32part.DATA_TYPE and part.name == "vfs":
|
|
offset_fs_vfs = part.offset
|
|
max_size_fs_vfs = 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),
|
|
("nvs", offset_nvs, max_size_nvs, arg_nvs_bin),
|
|
("application", offset_application, max_size_application, arg_application_bin),
|
|
("fs_sys", offset_fs_sys, max_size_fs_sys, arg_fs_sys_bin),
|
|
("fs_vfs", offset_fs_vfs, max_size_fs_vfs, arg_fs_vfs_bin),
|
|
]
|
|
|
|
# Remove files that are not present.
|
|
if arg_fs_vfs_bin == "none":
|
|
files_in.pop()
|
|
|
|
file_out = arg_output_bin
|
|
file_out_complete = os.path.abspath(arg_output_bin)
|
|
|
|
# Write output file with combined firmware.
|
|
cur_offset = 0
|
|
with open(file_out, "wb") as fout:
|
|
for name, offset, max_size, file_in in files_in:
|
|
if name == "fs_sys" and offset == 0:
|
|
continue
|
|
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 % 9d (% 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("%-23s%8d (% 8.1f MB)" % ("total", cur_offset, (cur_offset / 1024 / 1024)))
|
|
print(
|
|
"\r\nWrote 0x%x bytes to file m5stack/%s, ready to flash to offset 0x%x.\r\n\r\n"
|
|
"\033[1;32mExample command:\033[0m\r\n"
|
|
" \033[1;33m1.\033[0m make BOARD=%s BOARD_TYPE=%s PORT=/dev/ttyUSBx flash\r\n"
|
|
" \033[1;33m2.\033[0m esptool.py --chip %s --port /dev/ttyUSBx --baud 1500000 write_flash 0x%x %s"
|
|
% (
|
|
cur_offset,
|
|
file_out,
|
|
0x0,
|
|
file_out[6:].split("/")[0],
|
|
arg_board_type_flag.lower(),
|
|
idf_target.lower(),
|
|
0x0,
|
|
file_out_complete,
|
|
)
|
|
)
|
|
|
|
# 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__), "../micropython/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()))
|
|
|
|
# uiflow-0973efa-esp32s3-8mb-atoms3-v2.0.0-alpha-2-20230206.bin
|
|
today = date.today()
|
|
feature_str = ""
|
|
if idf_target == "ESP32C3":
|
|
if load_sdkconfig_str_value(arg_sdkconfig, "ESP_CONSOLE_USB_SERIAL_JTAG", "").upper() == "Y":
|
|
feature_str = "usb-"
|
|
else:
|
|
feature_str = load_sdkconfig_spiram_value(arg_sdkconfig).lower()
|
|
|
|
arg_board_type_flag = arg_board_type_flag + "-"
|
|
|
|
if arg_lvgl_flag == "1":
|
|
arg_lvgl_flag = "lvgl-"
|
|
else:
|
|
arg_lvgl_flag = ""
|
|
|
|
uiflow_version = ""
|
|
with open("./version.txt", "r") as f:
|
|
uiflow_version = f.readline() + "-"
|
|
|
|
release_file_out = "{}-{}-{}{}-{}{}{}{}.bin".format(
|
|
file_out_complete.split(".bin")[0],
|
|
idf_target.lower(),
|
|
feature_str.lower(),
|
|
load_sdkconfig_flash_size_value(arg_sdkconfig).lower(),
|
|
arg_board_type_flag.lower(),
|
|
arg_lvgl_flag,
|
|
uiflow_version.lower(),
|
|
today.strftime("%Y%m%d"),
|
|
)
|
|
print(
|
|
"\033[1;32mRelease Firmware:\033[0m\r\n \033[1;33m"
|
|
+ arg_board_type_flag[:-1].upper()
|
|
+ ":\033[0m "
|
|
+ release_file_out
|
|
)
|
|
os.system("cp {} {}".format(file_out, release_file_out))
|