write in 4096 byte chunks

This commit is contained in:
Brian S. Stephan 2023-07-12 17:33:12 -05:00
parent 8c5bd4397f
commit fb1729a957
Signed by: bss
GPG Key ID: 3DE06D3180895FCB
2 changed files with 53 additions and 23 deletions

View File

@ -198,28 +198,38 @@ def write(out_end: usb.core.Endpoint, in_end: usb.core.Endpoint, location: int,
location: memory address of where to start reading from
content: the data to write
"""
# not sure why 256 alignment isn't working but it leads to corruption
# maybe claims that erase need to be on 4096 byte sectors?
if (location % 4096) != 0:
raise PicoAlignmentError("writes must start at 4096 byte boundaries, please pad or align as appropriate!")
chunk_size = 4096
write_location = location
write_size = 0
if (location % chunk_size) != 0:
raise PicoAlignmentError(f"writes must start at {chunk_size} byte boundaries, "
f"please pad or align as appropriate!")
# set up the data
command_size = 8
size = len(content)
exclusive_access(out_end, in_end, is_exclusive=True)
exit_xip(out_end, in_end)
erase(out_end, in_end, location, len(content))
exit_xip(out_end, in_end)
pico_token = 1
logger.debug("writing %s bytes to %s", len(content), hex(location))
payload = struct.pack(PICOBOOT_CMD_STRUCT + PICOBOOT_CMD_READ_SUFFIX_STRUCT,
PICO_MAGIC, pico_token, PICO_COMMANDS['WRITE'], command_size, len(content),
location, len(content))
logger.debug("WRITE: %s", payload)
out_end.write(payload)
logger.debug("actually writing bytes now...")
logger.debug("payload: %s", content)
out_end.write(content)
res = in_end.read(256)
logger.debug("res: %s", res)
while write_size < size:
pico_token = 1
to_write = content[write_size:(write_size + chunk_size)]
exit_xip(out_end, in_end)
logger.debug("erasing %s bytes at %s", len(to_write), hex(write_location))
erase(out_end, in_end, write_location, len(to_write))
logger.debug("writing %s bytes to %s", len(to_write), hex(write_location))
payload = struct.pack(PICOBOOT_CMD_STRUCT + PICOBOOT_CMD_READ_SUFFIX_STRUCT,
PICO_MAGIC, pico_token, PICO_COMMANDS['WRITE'], command_size, len(to_write),
write_location, len(to_write))
logger.debug("WRITE: %s", payload)
out_end.write(payload)
logger.debug("actually writing bytes now...")
logger.debug("payload: %s", to_write)
out_end.write(bytes(to_write))
res = in_end.read(chunk_size)
logger.debug("res: %s", res)
write_size += chunk_size
write_location += chunk_size
exclusive_access(out_end, in_end, is_exclusive=False)

View File

@ -178,13 +178,34 @@ def test_write():
mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 1)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x3, 8, 0, 0x101FE000, 4)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x5, 8, 4, 0x101FE000, 4)),
mock.call(b'\x00\x01\x02\x03'),
mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 0)),
]
end_out.write.assert_has_calls(expected_writes)
assert end_in.read.call_count == 6
assert end_in.read.call_count == 5
def test_write_chunked():
"""Test that we can write to a board in BOOTSEL mode."""
end_out, end_in = mock.MagicMock(), mock.MagicMock()
payload = bytearray(b'\x00\x01\x02\x03' * 1024)
_ = pico.write(end_out, end_in, 0x10100000, payload * 2)
expected_writes = [
mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 1)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x3, 8, 0, 0x10100000, 4096)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x5, 8, 4096, 0x10100000, 4096)),
mock.call(bytes(payload)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x3, 8, 0, 0x10100000 + 4096, 4096)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x5, 8, 4096, 0x10100000 + 4096, 4096)),
mock.call(bytes(payload)),
mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 0)),
]
end_out.write.assert_has_calls(expected_writes)
assert end_in.read.call_count == 8
def test_misaligned_write():
@ -216,10 +237,9 @@ def test_misaligned_write():
mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 1)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x3, 8, 0, 0x101FF000, 4)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x5, 8, 4, 0x101FF000, 4)),
mock.call(b'\x00\x01\x02\x03'),
mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 0)),
]
end_out.write.assert_has_calls(expected_writes)
assert end_in.read.call_count == 6
assert end_in.read.call_count == 5