feat: add SMPSerialRawTransport for Zephyr raw UART SMP#106
Open
JPHutchins wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new raw (unencoded) SMP-over-UART transport for Zephyr’s CONFIG_MCUMGR_TRANSPORT_RAW_UART, while refactoring the existing base64/framed serial transport into a package with shared connection management.
Changes:
- Introduces
SMPSerialRawTransportimplementing Zephyr “raw UART” SMP message exchange ([8-byte header][payload]) with MTU-based send limiting. - Refactors existing
SMPSerialTransportto share connect/disconnect/TX drain/read helpers via a_SerialTransportBaseinserial/common.py. - Updates and expands the test suite, including a new end-to-end MTU-parametrized upload test for the raw transport.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_smp_serial_transport.py | Updates serial mocking target to the new serial.common.Serial location. |
| tests/test_smp_serial_raw_transport.py | Adds unit tests for the new raw serial transport behavior. |
| tests/test_smp_client.py | Adds an MTU-parametrized upload test exercising chunking with the raw transport. |
| tests/test_base64.py | Updates internal base64 helper imports to the new serial.encoded module. |
| src/smpclient/transport/serial/init.py | Re-exports SMPSerialTransport and SMPSerialRawTransport from the new package layout. |
| src/smpclient/transport/serial/common.py | Adds shared serial connection management and SerialException translation utilities. |
| src/smpclient/transport/serial/encoded.py | Moves encoded transport onto the shared serial base class; behavior largely preserved. |
| src/smpclient/transport/serial/unencoded.py | Implements the new raw SMP serial transport. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Zephyr 4.4 introduced CONFIG_MCUMGR_TRANSPORT_RAW_UART -- an SMP-over-UART
transport that sends each SMP message as raw [8-byte header][payload] bytes
with no framing, base64, or CRC. Smaller code size and faster transfers
than the historical "SMP over console" framing, at the cost of being unable
to share the UART with shell or log output.
Splits the single transport/serial.py into a package so the two
transports share connection management via a final-method base class:
serial/
__init__.py re-exports both transports
common.py _SerialTransportBase: pyserial holder, connect/disconnect,
SerialException -> SMPTransportDisconnected translation,
TX drain, RX polling helper
encoded.py SMPSerialTransport (unchanged: base64 + CRC + delimiters,
shell interleave via read_serial)
unencoded.py SMPSerialRawTransport (new: writes bytes verbatim,
reads SMP header then payload, raises on overrun and on
header lengths exceeding max_unencoded_size)
The from smpclient.transport.serial import SMPSerialTransport import path
is preserved -- existing users (including MCUboot serial recovery, which
still requires the base64 framing) need no changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
b0de5db to
d82c25f
Compare
Comment on lines
+101
to
+105
| logger.debug( | ||
| f"Failed to connect to {self._conn.port=}: {e}, " | ||
| f"retrying in {self._CONNECTION_RETRY_INTERVAL_S} seconds" | ||
| ) | ||
| await asyncio.sleep(self._CONNECTION_RETRY_INTERVAL_S) |
Comment on lines
+95
to
+105
| try: | ||
| self._conn.open() | ||
| self._conn.reset_input_buffer() | ||
| logger.debug(f"Connected to {self._conn.port=}") | ||
| return | ||
| except SerialException as e: | ||
| logger.debug( | ||
| f"Failed to connect to {self._conn.port=}: {e}, " | ||
| f"retrying in {self._CONNECTION_RETRY_INTERVAL_S} seconds" | ||
| ) | ||
| await asyncio.sleep(self._CONNECTION_RETRY_INTERVAL_S) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
SMPSerialRawTransportfor Zephyr 4.4'sCONFIG_MCUMGR_TRANSPORT_RAW_UART— the raw (unencoded) SMP-over-UART transport that sends each SMP message as[8-byte header][payload]bytes with no framing, base64, or CRC. Smaller code size and faster transfers than the historical "SMP over console" framing, at the cost of being unable to share the UART with shell or log output.The existing
serial.pyfile is split into a package so the two serial transports can share connection management via a@final-method base class:from smpclient.transport.serial import SMPSerialTransportcontinues to work — MCUboot serial recovery still needs the encoded transport (its Kconfig unconditionally selectsBASE64), no migration required for existing users.Related
UART_MCUMGR_RAW_PROTOCOLKconfig split that determines which transport appliessmpmgrwill need to expose the new transportTest plan
uv run task all(ruff + pydoclint + mypy + pytest) passesSMPSerialTransporttest suite passes unchanged (behavior-preserving refactor)SMPClient.upload()chunking against the raw transport over 7 MTU valuesCONFIG_MCUMGR_TRANSPORT_RAW_UART=ytarget🤖 Generated with Claude Code