flag and method to visualize the board config
via file dump or via USB. used to test the writing of the board config to binary Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
parent
1a44e8c1e3
commit
314fc909ff
|
@ -17,6 +17,7 @@ from gp2040ce_bintools.rp2040 import get_bootsel_endpoints, read
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
BOARD_CONFIG_BINARY_LOCATION = 0x1F8000
|
BOARD_CONFIG_BINARY_LOCATION = 0x1F8000
|
||||||
|
BOARD_CONFIG_BOOTSEL_ADDRESS = 0x10000000 + BOARD_CONFIG_BINARY_LOCATION
|
||||||
STORAGE_SIZE = 16384
|
STORAGE_SIZE = 16384
|
||||||
USER_CONFIG_BINARY_LOCATION = 0x1FC000
|
USER_CONFIG_BINARY_LOCATION = 0x1FC000
|
||||||
USER_CONFIG_BOOTSEL_ADDRESS = 0x10000000 + USER_CONFIG_BINARY_LOCATION
|
USER_CONFIG_BOOTSEL_ADDRESS = 0x10000000 + USER_CONFIG_BINARY_LOCATION
|
||||||
|
@ -124,13 +125,15 @@ def get_config_footer(content: bytes) -> tuple[int, int, str]:
|
||||||
return config_size, config_crc, config_magic
|
return config_size, config_crc, config_magic
|
||||||
|
|
||||||
|
|
||||||
def get_config_from_file(filename: str, whole_board: bool = False, allow_no_file: bool = False) -> Message:
|
def get_config_from_file(filename: str, whole_board: bool = False, allow_no_file: bool = False,
|
||||||
|
board_config: bool = False) -> Message:
|
||||||
"""Read the specified file (memory dump or whole board dump) and get back its config section.
|
"""Read the specified file (memory dump or whole board dump) and get back its config section.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filename: the filename of the file to open and read
|
filename: the filename of the file to open and read
|
||||||
whole_board: optional, if true, attempt to find the storage section from its normal location on a board
|
whole_board: optional, if true, attempt to find the storage section from its normal location on a board
|
||||||
allow_no_file: if true, attempting to open a nonexistent file returns an empty config, else it errors
|
allow_no_file: if true, attempting to open a nonexistent file returns an empty config, else it errors
|
||||||
|
board_config: if true, the board config is provided instead of the user config
|
||||||
Returns:
|
Returns:
|
||||||
the parsed configuration
|
the parsed configuration
|
||||||
"""
|
"""
|
||||||
|
@ -144,7 +147,10 @@ def get_config_from_file(filename: str, whole_board: bool = False, allow_no_file
|
||||||
return config_pb2.Config()
|
return config_pb2.Config()
|
||||||
|
|
||||||
if whole_board:
|
if whole_board:
|
||||||
return get_config(get_user_storage_section(content))
|
if board_config:
|
||||||
|
return get_config(get_board_storage_section(content))
|
||||||
|
else:
|
||||||
|
return get_config(get_user_storage_section(content))
|
||||||
else:
|
else:
|
||||||
return get_config(content)
|
return get_config(content)
|
||||||
|
|
||||||
|
@ -165,6 +171,15 @@ def get_config_from_usb(address: int) -> tuple[Message, object, object]:
|
||||||
return get_config(bytes(storage)), endpoint_out, endpoint_in
|
return get_config(bytes(storage)), endpoint_out, endpoint_in
|
||||||
|
|
||||||
|
|
||||||
|
def get_board_config_from_usb() -> tuple[Message, object, object]:
|
||||||
|
"""Read the board configuration from the detected USB device.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
the parsed configuration, along with the USB out and in endpoints for reference
|
||||||
|
"""
|
||||||
|
return get_config_from_usb(BOARD_CONFIG_BOOTSEL_ADDRESS)
|
||||||
|
|
||||||
|
|
||||||
def get_user_config_from_usb() -> tuple[Message, object, object]:
|
def get_user_config_from_usb() -> tuple[Message, object, object]:
|
||||||
"""Read the user configuration from the detected USB device.
|
"""Read the user configuration from the detected USB device.
|
||||||
|
|
||||||
|
@ -286,6 +301,8 @@ def visualize():
|
||||||
)
|
)
|
||||||
parser.add_argument('--whole-board', action='store_true', help="indicate the binary file is a whole board dump")
|
parser.add_argument('--whole-board', action='store_true', help="indicate the binary file is a whole board dump")
|
||||||
parser.add_argument('--json', action='store_true', help="print the config out as a JSON document")
|
parser.add_argument('--json', action='store_true', help="print the config out as a JSON document")
|
||||||
|
parser.add_argument('--board-config', action='store_true', default=False,
|
||||||
|
help="display the board config rather than the user config")
|
||||||
group = parser.add_mutually_exclusive_group(required=True)
|
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 "
|
group.add_argument('--usb', action='store_true', help="retrieve the config from a RP2040 board connected over USB "
|
||||||
"and in BOOTSEL mode")
|
"and in BOOTSEL mode")
|
||||||
|
@ -295,9 +312,12 @@ def visualize():
|
||||||
args, _ = parser.parse_known_args()
|
args, _ = parser.parse_known_args()
|
||||||
|
|
||||||
if args.usb:
|
if args.usb:
|
||||||
config, _, _ = get_user_config_from_usb()
|
if args.board_config:
|
||||||
|
config, _, _ = get_board_config_from_usb()
|
||||||
|
else:
|
||||||
|
config, _, _ = get_user_config_from_usb()
|
||||||
else:
|
else:
|
||||||
config = get_config_from_file(args.filename, whole_board=args.whole_board)
|
config = get_config_from_file(args.filename, whole_board=args.whole_board, board_config=args.board_config)
|
||||||
|
|
||||||
if args.json:
|
if args.json:
|
||||||
print(MessageToJson(config))
|
print(MessageToJson(config))
|
||||||
|
|
Binary file not shown.
|
@ -94,6 +94,15 @@ def test_get_config_from_file_whole_board_dump():
|
||||||
assert config.addonOptions.bootselButtonOptions.enabled is False
|
assert config.addonOptions.bootselButtonOptions.enabled is False
|
||||||
|
|
||||||
|
|
||||||
|
@with_pb2s
|
||||||
|
def test_get_board_config_from_file_whole_board_dump():
|
||||||
|
"""Test that we can open a storage dump file and find its config."""
|
||||||
|
filename = os.path.join(HERE, 'test-files', 'test-whole-board-with-board-config.bin')
|
||||||
|
config = storage.get_config_from_file(filename, whole_board=True, board_config=True)
|
||||||
|
assert config.boardVersion == 'v0.7.6-15-g71f4512'
|
||||||
|
assert config.addonOptions.bootselButtonOptions.enabled is False
|
||||||
|
|
||||||
|
|
||||||
@with_pb2s
|
@with_pb2s
|
||||||
def test_get_config_from_file_file_not_fonud_ok():
|
def test_get_config_from_file_file_not_fonud_ok():
|
||||||
"""If we allow opening a file that doesn't exist (e.g. for the editor), check we get an empty config."""
|
"""If we allow opening a file that doesn't exist (e.g. for the editor), check we get an empty config."""
|
||||||
|
@ -164,6 +173,24 @@ def test_pad_config_to_storage_raises(config_binary):
|
||||||
_ = storage.pad_config_to_storage_size(config_binary * 5)
|
_ = storage.pad_config_to_storage_size(config_binary * 5)
|
||||||
|
|
||||||
|
|
||||||
|
@with_pb2s
|
||||||
|
def test_get_board_config_from_usb(config_binary):
|
||||||
|
"""Test we attempt to read from the proper location over USB."""
|
||||||
|
mock_out = mock.MagicMock()
|
||||||
|
mock_out.device.idVendor = 0xbeef
|
||||||
|
mock_out.device.idProduct = 0xcafe
|
||||||
|
mock_out.device.bus = 1
|
||||||
|
mock_out.device.address = 2
|
||||||
|
mock_in = mock.MagicMock()
|
||||||
|
with mock.patch('gp2040ce_bintools.storage.get_bootsel_endpoints', return_value=(mock_out, mock_in)) as mock_get:
|
||||||
|
with mock.patch('gp2040ce_bintools.storage.read', return_value=config_binary) as mock_read:
|
||||||
|
config, _, _ = storage.get_board_config_from_usb()
|
||||||
|
|
||||||
|
mock_get.assert_called_once()
|
||||||
|
mock_read.assert_called_with(mock_out, mock_in, 0x101F8000, 16384)
|
||||||
|
assert config == storage.get_config(config_binary)
|
||||||
|
|
||||||
|
|
||||||
@with_pb2s
|
@with_pb2s
|
||||||
def test_get_user_config_from_usb(config_binary):
|
def test_get_user_config_from_usb(config_binary):
|
||||||
"""Test we attempt to read from the proper location over USB."""
|
"""Test we attempt to read from the proper location over USB."""
|
||||||
|
|
Loading…
Reference in New Issue