MeshTalos-Client/managed_components/espressif__esp_rcp_update/create_ota_image.py
2025-12-03 14:20:11 +08:00

94 lines
3.5 KiB
Python

#!/usr/bin/env python3
import os
import sys
import argparse
import pathlib
import shutil
import struct
FILETAG_RCP_VERSION = 0
FILETAG_RCP_FLASH_ARGS = 1
FILETAG_RCP_BOOTLOADER = 2
FILETAG_RCP_PARTITION_TABLE = 3
FILETAG_RCP_FIRMWARE = 4
FILETAG_BR_OTA_IMAGE = 5
FILETAG_IMAGE_HEADER = 0xff
HEADER_ENTRY_SIZE = 3 * 4
RCP_IMAGE_HEADER_SIZE = HEADER_ENTRY_SIZE * 6
RCP_FLASH_ARGS_SIZE = 2 * 4 * 3
def append_subfile_header(fout, tag, size, offset):
fout.write(struct.pack('<LLL', tag, size, offset))
return offset + size
def append_subfile(fout, target_file):
buf_size = 4096
with open(target_file, 'rb') as fin:
data = fin.read(buf_size)
while data and len(data) > 0:
fout.write(data)
data = fin.read(buf_size)
def append_flash_args(fout, flash_args_path):
with open(flash_args_path, 'r') as f:
# skip first line
next(f)
partition_info_list = [l.split() for l in f]
for offset, partition_file in partition_info_list:
offset = int(offset, 0)
if partition_file.find('bootloader') >= 0:
fout.write(struct.pack('<LL', FILETAG_RCP_BOOTLOADER, offset))
elif partition_file.find('partition_table') >= 0:
fout.write(struct.pack('<LL', FILETAG_RCP_PARTITION_TABLE, offset))
else:
fout.write(struct.pack('<LL', FILETAG_RCP_FIRMWARE, offset))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--rcp-build-dir', type=str, required=True)
parser.add_argument('--br-firmware', type=str, required=False)
parser.add_argument('--target-file', type=str, required=True)
args = parser.parse_args()
base_dir = args.rcp_build_dir
pathlib.Path(os.path.dirname(args.target_file)).mkdir(parents=True, exist_ok=True)
rcp_version_path = os.path.join(base_dir, 'rcp_version')
flash_args_path = os.path.join(base_dir, 'flash_args')
bootloader_path = os.path.join(base_dir, 'bootloader', 'bootloader.bin')
partition_table_path = os.path.join(
base_dir, 'partition_table', 'partition-table.bin')
rcp_firmware_path = os.path.join(base_dir, 'esp_ot_rcp.bin')
with open(args.target_file, 'wb') as fout:
image_header_size = RCP_IMAGE_HEADER_SIZE
if args.br_firmware:
image_header_size += HEADER_ENTRY_SIZE
offset = append_subfile_header(
fout, FILETAG_IMAGE_HEADER, image_header_size, 0)
offset = append_subfile_header(
fout, FILETAG_RCP_VERSION, os.path.getsize(rcp_version_path), offset)
offset = append_subfile_header(
fout, FILETAG_RCP_FLASH_ARGS, RCP_FLASH_ARGS_SIZE, offset)
offset = append_subfile_header(
fout, FILETAG_RCP_BOOTLOADER, os.path.getsize(bootloader_path), offset)
offset = append_subfile_header(
fout, FILETAG_RCP_PARTITION_TABLE, os.path.getsize(partition_table_path), offset)
offset = append_subfile_header(
fout, FILETAG_RCP_FIRMWARE, os.path.getsize(rcp_firmware_path), offset)
if args.br_firmware:
offset = append_subfile_header(fout, FILETAG_BR_OTA_IMAGE, os.path.getsize(args.br_firmware), offset)
append_subfile(fout, rcp_version_path)
append_flash_args(fout, flash_args_path)
append_subfile(fout, bootloader_path)
append_subfile(fout, partition_table_path)
append_subfile(fout, rcp_firmware_path)
if args.br_firmware:
append_subfile(fout, args.br_firmware)
if __name__ == '__main__':
main()