support writing new configs as .uf2 files via the TUI

`edit-config --filename foo.uf2` can now create standalone config UF2
files. still working on reading UF2s, or maybe what edit-config needs is
a "Save As..." in order to read from a board/config and output it to a
new file, but this is a start

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
Brian S. Stephan 2024-03-25 11:45:02 -05:00
parent 449812f1df
commit f6d3ad02e0
Signed by: bss
GPG Key ID: 3DE06D3180895FCB
3 changed files with 29 additions and 6 deletions

View File

@ -214,11 +214,16 @@ def write_new_config_to_filename(config: Message, filename: str, inject: bool =
with open(filename, 'rb') as file:
existing_binary = file.read()
binary = replace_config_in_binary(bytearray(existing_binary), config_binary)
with open(filename, 'wb') as file:
file.write(binary)
else:
binary = serialize_config_with_footer(config)
with open(filename, 'wb') as file:
file.write(binary)
with open(filename, 'wb') as file:
if filename[-4:] == '.uf2':
file.write(convert_binary_to_uf2(pad_config_to_storage_size(binary),
start=USER_CONFIG_BINARY_LOCATION))
else:
file.write(binary)
def write_new_config_to_usb(config: Message, endpoint_out: object, endpoint_in: object):

View File

@ -409,8 +409,9 @@ def edit_config():
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--usb', action='store_true', help="retrieve the config from a RP2040 board connected over USB "
"and in BOOTSEL mode")
group.add_argument('--filename', help=".bin file of a GP2040-CE board's config + footer or entire storage section, "
"or of a GP2040-CE's whole board dump if --whole-board is specified")
group.add_argument('--filename', help=".bin of a GP2040-CE's whole board dump if --whole-board is specified, or a"
".bin file of a GP2040-CE board's config + footer or entire storage section; "
"if creating a new config, it can also be written in .uf2 format")
args, _ = parser.parse_known_args()
if args.usb:

View File

@ -15,7 +15,7 @@ from gp2040ce_bintools.builder import (FirmwareLengthError, combine_firmware_and
concatenate_firmware_and_storage_files, get_gp2040ce_from_usb,
pad_binary_up_to_board_config, pad_binary_up_to_user_config,
replace_config_in_binary, write_new_config_to_filename, write_new_config_to_usb)
from gp2040ce_bintools.storage import (get_board_storage_section, get_config, get_config_footer,
from gp2040ce_bintools.storage import (STORAGE_SIZE, get_board_storage_section, get_config, get_config_footer,
get_user_storage_section, serialize_config_with_footer)
HERE = os.path.dirname(os.path.abspath(__file__))
@ -272,6 +272,23 @@ def test_write_new_config_to_config_bin(firmware_binary, tmp_path):
assert len(config_dump) == config_size + 12
@with_pb2s
def test_write_new_config_to_config_uf2(firmware_binary, tmp_path):
"""Test that the config can be written to a file."""
tmp_file = os.path.join(tmp_path, 'config.uf2')
config_pb2 = get_config_pb2()
config = config_pb2.Config()
config.boardVersion = 'v0.7.5-COOL'
write_new_config_to_filename(config, tmp_file)
# read new file
with open(tmp_file, 'rb') as file:
config_dump = file.read()
# the current implementation of UF2 writing does it in 256 blocks, so each 256 byte block of
# binary is 512 bytes in the UF2
assert len(config_dump) == STORAGE_SIZE * 2
@with_pb2s
def test_write_new_config_to_usb(config_binary):
"""Test that the config can be written to USB at the proper alignment."""