Bootloader-equipped NexatomTT hardware can start in firmware service (BOOTLOADER) mode before running its measurement image. Other supported devices may already be in runtime, including legacy Zynq hardware without a bootloader. Applications use the same native runtime-entry operation for measurement readiness rather than assuming one initial state from a product name.
The native API owns discovery, service/image boot transitions, initialization and profile resolution. The client selects an instrument and an intended measurement; ordinary startup requires no manual protocol or hardware-profile selection.
UTT810 units without a bootloader. Early UTT810 units were delivered without the bootloader. They still connect directly to their runtime and measure as before. To use firmware slots and field updates, such a unit needs a one-time bootloader installation by Nexatom service; contact Nexatom to arrange it. After that, firmware updates run through the SDK and the app like on any other unit.
open_runtime_device() context managerThe nexatomtt.runtime_boot module provides open_runtime_device(library, device_info, options=...). Its default path calls native connect_runtime() on one created handle. Native boots an existing valid image if needed, waits for runtime/profile readiness and retains that same handle and its ownership.
stateDiagram-v2
[*] --> Detect : connect_runtime on selected handle
Detect --> Service : Firmware service detected
Detect --> Runtime : Runtime already present
Service --> SelectSlot : Inspect existing valid images
SelectSlot --> Runtime : Native boot and transition handling
Runtime --> Ready : Native initialization and profile authorization
Ready --> [*] : Yield same NexatomDevice
Usage:
from nexatomtt import NexatomLibrary, open_runtime_device, RuntimeBootOptions
library = NexatomLibrary(home="/path/to/extracted-sdk")
devices = library.discover_devices()
if len(devices) != 1:
# With several boards, pick one by its connection_id (its USB port).
raise RuntimeError("Select one intended board before starting")
options = RuntimeBootOptions(timeout_ms=20000)
with open_runtime_device(library, devices[0], options=options) as device:
# Ready for supported controls; connecting has not started a measurement.
profile = device.get_device_profile()
print("Available channels:", hex(profile.effective_public_tdc_mask))
# Configure and acquire using the complete tutorial's explicit start/stop.
device.disconnect() # Check shutdown before context-manager destruction.
Bootloader-equipped devices expose their slot inventory. Use the reported slot count rather than assuming a fixed number of slots. When a service-mode boot is required, selection follows this priority:
options.preferred_slot, the helper requests that slot. If the slot is not VALID, selection fails rather than falling back.An explicit preferred_slot is useful for deliberate firmware-service work. If the device is already in runtime, the helper completes readiness there; it does not force a boot of that slot. Ordinary runtime entry does not load an image, modify flash, or change the persistent default. Those are separate field-update operations.
Boot changes the device’s protocol and runtime state; it must not be treated as proof of measurement readiness merely because the boot command was acknowledged. Native waits for the required runtime evidence and handles the transition on the existing device handle. A physical USB re-enumeration is not a mandatory client-visible step on every model.
Keep the selected device’s complete discovery record. Its connection_id (usb: plus the USB port path) identifies the board and stays the same through the boot while the board stays in that port; the FT601 USB serial is information only and never identifies a board. The DeviceIdentity helper remains available for describing selection records; normal applications do not implement a second discovery/reconnect loop around native runtime entry. Each handle owns one board; to run several boards, open one handle per board.
Advanced firmware examples can deliberately close and reopen a device to prove that a later independent session works. That additional validation is distinct from the boot operation’s same-handle readiness contract.
Cold startup can need more time than attachment to an existing runtime. RuntimeBootOptions retains the following settings:
timeout_ms: Budget for native protocol/readiness waits. A value such as 20000 ms allows cold startup without an arbitrary client sleep. In-flight I/O and cleanup may finish after that budget; it is not a hard wall-clock limit on every call.mode_timeout_sec and poll_sec: Compatibility settings used only for protocol detection in the explicit preferred-slot workflow, not a normal Python USB discovery loop.If startup times out, identity is unsupported, or no valid image exists, report the native exception or RuntimeBootError with its diagnostic message. Do not replace that failure with fixed-delay retries or manual protocol selection. Preserve cleanup errors as part of the outcome. See the runtime/service tutorial for deliberate return-to-service operations; they are separate from normal measurement entry.