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 location: memory address of where to start reading from
content: the data to write content: the data to write
""" """
# not sure why 256 alignment isn't working but it leads to corruption chunk_size = 4096
# maybe claims that erase need to be on 4096 byte sectors? write_location = location
if (location % 4096) != 0: write_size = 0
raise PicoAlignmentError("writes must start at 4096 byte boundaries, please pad or align as appropriate!")
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 # set up the data
command_size = 8 command_size = 8
size = len(content)
exclusive_access(out_end, in_end, is_exclusive=True) exclusive_access(out_end, in_end, is_exclusive=True)
exit_xip(out_end, in_end) while write_size < size:
erase(out_end, in_end, location, len(content)) pico_token = 1
exit_xip(out_end, in_end) to_write = content[write_size:(write_size + chunk_size)]
pico_token = 1
logger.debug("writing %s bytes to %s", len(content), hex(location)) exit_xip(out_end, in_end)
payload = struct.pack(PICOBOOT_CMD_STRUCT + PICOBOOT_CMD_READ_SUFFIX_STRUCT, logger.debug("erasing %s bytes at %s", len(to_write), hex(write_location))
PICO_MAGIC, pico_token, PICO_COMMANDS['WRITE'], command_size, len(content), erase(out_end, in_end, write_location, len(to_write))
location, len(content))
logger.debug("WRITE: %s", payload) logger.debug("writing %s bytes to %s", len(to_write), hex(write_location))
out_end.write(payload) payload = struct.pack(PICOBOOT_CMD_STRUCT + PICOBOOT_CMD_READ_SUFFIX_STRUCT,
logger.debug("actually writing bytes now...") PICO_MAGIC, pico_token, PICO_COMMANDS['WRITE'], command_size, len(to_write),
logger.debug("payload: %s", content) write_location, len(to_write))
out_end.write(content) logger.debug("WRITE: %s", payload)
res = in_end.read(256) out_end.write(payload)
logger.debug("res: %s", res) 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) 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('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 1)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)), 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('<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(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x5, 8, 4, 0x101FE000, 4)),
mock.call(b'\x00\x01\x02\x03'), mock.call(b'\x00\x01\x02\x03'),
mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 0)), mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 0)),
] ]
end_out.write.assert_has_calls(expected_writes) 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(): 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('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 1)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)), 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('<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(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x5, 8, 4, 0x101FF000, 4)),
mock.call(b'\x00\x01\x02\x03'), mock.call(b'\x00\x01\x02\x03'),
mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 0)), mock.call(struct.pack('<LLBBxxLL12x', 0x431fd10b, 1, 0x1, 1, 0, 0)),
] ]
end_out.write.assert_has_calls(expected_writes) end_out.write.assert_has_calls(expected_writes)
assert end_in.read.call_count == 6 assert end_in.read.call_count == 5