host.embedded_transfer

Console file transfer for embedded hosts.

UnixHost’s FileTransfer dispatches scp/sftp/ftp/netcat — none of which exist on a bare-metal/RTOS target. EmbeddedFileTransfer is the embedded analogue: it speaks only the device’s own shell, and an EmbeddedHost delegates get/put to it exactly as UnixHost delegates to FileTransfer.

Backends

The backend is a typed, declared-per-host choice (the host’s transfer field), never a fixed mechanism: embedded systems share no universal file transfer protocol, so otto standardizes on a pluggable backend instead. Adding a future backend (YMODEM, MCUmgr, a vendor mechanism) is then additive.

  • console (default) — the Zephyr fs shell. get runs fs read and decodes the hexdump; put runs chunked fs write calls. Requires the target firmware to enable CONFIG_FILE_SYSTEM_SHELL over a mounted filesystem, and the host’s filesystem field in lab data to declare a real FS (not NoFileSystem). When the declaration is none, get/put short-circuit with a clear error (_NO_FILESYSTEM_MSG) before any shell command runs.

  • tftp — reserved (see TftpOptions); the body raises NotImplementedError (deferred).

Why console transfer is slow

Every byte crosses the shell as ~3 characters of hex text (fs write) or is read back inside a hexdump (fs read), one bounded command at a time. That is fine for test artifacts and configuration files — kilobytes — but it is not a path for firmware images; use TFTP (once implemented) for bulk data.

show_progress drives the same shared Rich progress bar as the Unix transfers: put reports genuine per-chunk progress (one event per 32-byte fs write — finer than asyncssh’s 256 KB SCP block), and get reports a single completion event at 100% because fs read is monolithic (per-byte GET progress would need chunked fs read <path> <off> <len>; deferred).

class otto.host.embedded_transfer.EmbeddedFileTransfer(transfer, name, exec_cmd, filesystem=None, max_filename_len=255)

Bases: BaseFileTransfer

File transfer for an embedded host, over the device shell only.

Subclasses BaseFileTransfer, inheriting its put_files / get_files API (filename-length validation, shared Rich progress acquisition). Implements the abstract _run_put / _run_get against the device’s fs shell. The shell command runner is injected as exec_cmd so the class is testable against a fake shell with no real connection.

host_families : --is-rst--:py:class:`frozenset`\ \[:py:class:`str`] = frozenset({'embedded'})

a subset of {'unix', 'embedded'}. Subclasses declare it; the spec field_validator rejects a backend on a host of the wrong family. A backend with an empty set can never validate and is rejected at registration.

Type:

Host families this backend serves

classmethod create(ctx)

Build a transfer backend from a TransferContext.

The uniform construction seam (WS#4). Concrete backends override this to run their exact construction against the ctx fields they need. Not an abstractmethod deliberately: only registered built-ins are ever constructed through create, and test doubles that subclass BaseFileTransfer only to exercise the progress contract must not be forced to implement it.

Return type:

EmbeddedFileTransfer