pico.write must happen at 256 byte boundaries

there's no good way to tell if the payload should be padded or if it
should just be realigned, so raise an exception and make the caller
figure it out
This commit is contained in:
Brian S. Stephan 2023-07-09 09:16:55 -05:00
parent c25f6f4fd3
commit 2d024c5b34
Signed by: bss
GPG Key ID: 3DE06D3180895FCB
2 changed files with 46 additions and 0 deletions

View File

@ -32,6 +32,15 @@ PICO_COMMANDS = {
}
#################
# LIBRARY ITEMS #
#################
class PicoAlignmentError(ValueError):
"""Exception raised when the address provided for an operation is invalid."""
def get_bootsel_endpoints() -> tuple[usb.core.Endpoint, usb.core.Endpoint]:
"""Retrieve the USB endpoint for purposes of interacting with a Pico in BOOTSEL mode.
@ -189,6 +198,9 @@ 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
"""
if (location % 256) != 0:
raise PicoAlignmentError("writes must start at 256 byte boundaries, please pad or align as appropriate!")
# set up the data
command_size = 8

View File

@ -5,6 +5,7 @@ import sys
import unittest.mock as mock
from array import array
import pytest
from decorator import decorator
import gp2040ce_bintools.pico as pico
@ -144,3 +145,36 @@ def test_write():
]
end_out.write.assert_has_calls(expected_writes)
assert end_in.read.call_count == 6
def test_misaligned_write():
"""Test that we can't write to a board at invalid memory addresses."""
end_out, end_in = mock.MagicMock(), mock.MagicMock()
with pytest.raises(pico.PicoAlignmentError):
_ = pico.write(end_out, end_in, 0x101FE001, b'\x00\x01\x02\x03')
with pytest.raises(pico.PicoAlignmentError):
_ = pico.write(end_out, end_in, 0x101FE008, b'\x00\x01\x02\x03')
with pytest.raises(pico.PicoAlignmentError):
_ = pico.write(end_out, end_in, 0x101FE010, b'\x00\x01\x02\x03')
with pytest.raises(pico.PicoAlignmentError):
_ = pico.write(end_out, end_in, 0x101FE020, b'\x00\x01\x02\x03')
with pytest.raises(pico.PicoAlignmentError):
_ = pico.write(end_out, end_in, 0x101FE040, b'\x00\x01\x02\x03')
with pytest.raises(pico.PicoAlignmentError):
_ = pico.write(end_out, end_in, 0x101FE080, b'\x00\x01\x02\x03')
with pytest.raises(pico.PicoAlignmentError):
_ = pico.write(end_out, end_in, 0x101FE0FF, b'\x00\x01\x02\x03')
_ = pico.write(end_out, end_in, 0x101FE100, b'\x00\x01\x02\x03')
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, 0x101FE100, 4)),
mock.call(struct.pack('<LLBBxxL16x', 0x431fd10b, 1, 0x6, 0, 0)),
mock.call(struct.pack('<LLBBxxLLL8x', 0x431fd10b, 1, 0x5, 8, 4, 0x101FE100, 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