Firmware 0.6.1 · PBLE/1

How PyBLE firmware works

A functional view of PyBLE firmware 0.6.1—from the tablet app over Bluetooth Low Energy to the embedded agent and MicroPython runtime. This is a versioned reference, not a live installer promise, board drawing, or pinout.

Before provisioning, check current firmware availability for the exact profile and active release selected today.

One control plane · five exact profiles

Functional block diagram

Follow the app, BLE transport, protocol engine, agent services, and normal MicroPython runtime from left to right. On a small screen, scroll the diagram or open the full-size vector.

Functional block diagram of PyBLE firmware 0.6.1, from the tablet app over BLE and PBLE/1 to files, execution, console, boot, and five exact release profiles; it is not a board drawing, schematic, or pinout

Original PyBLE diagram for firmware 0.6.1. This is a protocol and runtime diagram—not a board drawing, automatic board detector, schematic, or pinout.

Open full-size SVG diagram (opens in a new tab)

Contract hardening · no new wire operations

What changed in v0.6.1

The same 24 PBLE/1 operations, 15 capability keys, and five profiles, with stricter implementation boundaries.

Session and message validation

HELLO negotiates PBLE/1 per connection. Commands require nonzero request IDs, valid direction, and exact payloads. Incomplete fragments expire after five seconds; eight protocol violations end the session. This is robustness, not authentication.

Fresh program state

File, inline-source, and autorun executions receive fresh globals. Prior variables do not leak into the next run. This is not a full VM reset: imported modules, hardware state, working directory, and sys.path can persist.

Run-owned console input

stdin is cleared at run admission, accepted Stop, terminal state, disconnect, and VM reset. Idle input is discarded. The bounded queue can still drop overflow; later runs never inherit those queued bytes.

Safer file transfers

Resume uses a completely read, CRC-checked regular-file prefix. PUT admission reserves 64 KiB of storage headroom. DELETE, MKDIR, and RENAME return EBUSY during PUT or GET; LIST and STAT remain available. CRC failure never replaces the destination.

Non-destructive storage recovery

All five official profiles mount LFS2. After mount failure, formatting requires a conclusively erased complete workspace device. Nonblank or uncertain media is preserved; agent and autorun startup are skipped for explicit USB recovery. Back up and use the documented installer when migrating an older FAT workspace.

Checked persistent settings

Labels, autorun, and ESP Identify configuration are validated before use. Persistence failures leave prior behavior in effect; invalid stored autorun is disabled. Internal configuration fault tracking adds no new PBLE/1 field.

Accessible diagram equivalent

Diagram description

Read from left to right, the diagram begins with the PyBLE app on iPadOS or Android. After a separate one-time wired installation, the app discovers a board, reads its capabilities, manages files, runs and stops code, sends console input, and receives standard output and errors over Bluetooth Low Energy. ESP images use desktop Chromium and Web Serial; Pico 2 W uses a verified UF2 download and manual BOOTSEL copy. Installation replaces the existing firmware and workspace.

Inside the compatible-device boundary, RX writes, TX notifications, and the readable INFO characteristic connect the app to the BLE GATT transport. Transport, identity, boot, and security modules feed the central PBLE/1 protocol engine. PBLE/1 version 1 defines 24 opcodes for device information, files, execution, console, labels, autorun, and optional Identify control. Frames carry request IDs and CRC-32 checks.

Below the engine, the filesystem bridge lists and inspects files, downloads from an offset, resumes windowed uploads, verifies CRC-32, and commits through a temporary .pbltmp sibling and rename. The run controller executes one file or inline source at a time with fresh globals and supports idempotent Stop and soft reboot. Imported modules and hardware state are not reset by fresh globals. The console carries tagged standard output and error plus bounded, run-owned stdin; idle input is discarded. Connection-generation and virtual-machine-epoch controls discard stale work after disconnects or resets.

The agent runs beside a normal upstream MicroPython 1.28.0 user runtime with zero PyBLE patches to upstream MicroPython. User programs retain ordinary filesystem and machine APIs and must select pins and buses explicitly; PyBLE does not detect a carrier board or supply a pin map.

The lower strip distinguishes five firmware 0.6.1 profiles. Four ESP profiles use the native C agent, NimBLE, LFS2 storage, upload window eight, and Web Serial. Pico 2 W uses the frozen-Python agent, BTstack, LFS2, upload window four, and manual UF2 provisioning. Memory alone does not identify a board, and matching N16R8 hardware does not make an arbitrary ESP32-S3 board the Waveshare B version.

Complete release surface

Complete PBLE/1 feature reference

These are firmware-agent capabilities. Hardware behavior still depends on the exact profile, board, wiring, and user program.

BLE transport

One PyBLE-owned GATT service. RX accepts Write and Write Without Response; TX notifies; INFO is readable. The app prefers ATT MTU 247, while fragmentation and reassembly keep the transport valid down to MTU 23.

Identity and capabilities

HELLO comes first. DEVICE_INFO and INFO expose 15 emitted keys: proto, agent, chip, mpy, fs_root, mtu, window, chunk, free_mem, has_sd, has_identify, identify_led, auto_run, device_id, and label. Labels are at most 24 UTF-8 bytes.

Safe boot and persistence

The embedded agent starts independently of the editable workspace, advertises and waits by default, and runs /main.py only after autorun is enabled. A broken main.py is separate from workspace mount failure: nonblank or uncertain media that cannot mount is preserved for explicit USB recovery, without agent or autorun startup.

Security and privacy

PBLE/1 has no application-layer authentication: a connected client is trusted. Device identity and labels are display-only, an advertised label is public, and the PyBLE agent sends no telemetry or code to a cloud service.

PBLE/1 protocol

Version 1 frames carry a command, response, or event, a request ID, and CRC-32. The dispatcher returns explicit status values and keeps transport framing separate from filesystem, runner, console, and identity services.

Files

List, stat, offset download, CRC-verified windowed upload, cumulative acknowledgement, reconnect resume, delete files or empty directories, mkdir, and rename. One transfer is active at a time; paths are limited to 128 bytes; .mpy and .pyc transfers are rejected.

Run and control

Run one workspace path of at most 128 bytes or inline UTF-8 source of at most 2,048 bytes. Observe idle, running, done, or error state; Stop is idempotent; soft reboot responds before its side effect; /main.py autorun is opt-in.

Live console

Tagged stdout and stderr travel to the app, while stdin supports input() and sys.stdin. Output chunks are at most 200 bytes and input staging is 256 bytes. Congestion can drop output, so the console is live feedback rather than a lossless log.

Lifecycle and reliability

BLE remains serviceable while user code runs. Bounded queues plus connection-generation and virtual-machine-epoch binding prevent stale work from crossing disconnects or resets. Pico 2 W returns EBUSY for file transfer while a program runs.

MicroPython runtime

Upstream MicroPython 1.28.0 runs with zero PyBLE upstream patches. All five profiles use LFS2; ESP includes upstream NeoPixel. Programs keep ordinary filesystem, machine, VFS, and asyncio APIs with explicit pins and buses—there is no automatic board or pin detection.

PBLE/1 version 1

All 24 operation identities

Events and no-response writes share these public identities; their direction and framing are defined by the protocol.

Identity

  • HELLO
  • DEVICE_INFO

Files

  • FILE_LIST
  • FILE_STAT
  • FILE_GET_BEGIN
  • FILE_GET_DATA
  • FILE_GET_END
  • FILE_PUT_BEGIN
  • FILE_PUT_DATA
  • FILE_PUT_END
  • FILE_DELETE
  • MKDIR
  • FILE_RENAME
  • FILE_PUT_ACK

Execution

  • RUN
  • STOP
  • SOFT_REBOOT
  • SET_AUTORUN
  • RUN_STATE

Console

  • CONSOLE_DATA
  • CONSOLE_INPUT

Device controls

  • SET_LABEL
  • SET_IDENTIFY_LED
  • IDENTIFY

Exact image constraints

Firmware 0.6.1 profiles

Published on the project owner's qualification confirmation. Profile constraints select firmware bytes; they do not visually identify a carrier board or promise a pin map.

Five exact release profiles in firmware 0.6.1. These are image constraints, not visual board detection or an exhaustive carrier-board allowlist.
ProfileExact hardware constraintAgent and runtimeProvisioning method
esp32-4mbClassic ESP32; exactly 4 MiB flash; no PSRAM required.Native C agent, NimBLE, LFS2, upstream NeoPixel, upload window 8.ESP Web Serial; select the matching 4 MiB ESP32 profile.
esp32-s3-n16r8ESP32-S3; exactly 16 MiB flash and 8 MiB Octal PSRAM.Lean, board-neutral N16R8 image; native C agent, NimBLE, LFS2, upload window 8; no TFT or boot splash.ESP Web Serial; select the lean generic N16R8 profile.
waveshare-esp32-s3-lcd-147bExact ESP32-S3-LCD-1.47B B-version; 16 MiB flash and 8 MiB Octal PSRAM.Native C agent, NimBLE, LFS2, upload window 8; pyble_st7789 runtime and fresh-install splash.ESP Web Serial; select only the exact Waveshare B-version profile.
esp32-c3-4mbESP32-C3 revision v0.3 or newer; exactly 4 MiB flash; no PSRAM.Native C agent, NimBLE, LFS2, upstream NeoPixel, upload window 8.ESP Web Serial; check revision v0.3+ and 4 MiB flash.
rpi-pico2-wExact Raspberry Pi Pico 2 W; RP2350 with CYW43439.Frozen-Python agent, BTstack, LFS2, upload window 4; named LED is available. Identify and NeoPixel are not claimed; transfer during RUN returns EBUSY.Verified UF2 download followed by a manual BOOTSEL copy.

Limits and safe use

Know the boundaries.

Install only the exact matching profile: provisioning replaces installed firmware and user files. A matching chip family does not prove flash size, PSRAM type, silicon revision, or board wiring.

PBLE/1 trusts the connected client, so use it only where nearby BLE clients are trusted. The advertised label is public. This release reports no SD card, allows one program and one active transfer class, does not recursively delete folders, and rejects compiled .mpy and .pyc transfers.

User code can defeat remote Stop by calling micropython.kbd_intr(-1). Console output may be dropped during sustained congestion. The PBLE/1 workspace jail protects the agent from PBLE/1 file commands; user MicroPython code retains ordinary os and VFS access.

Versioned evidence

Inspect the release, then put it to work.

This reference is bound to firmware 0.6.1 and source c8f549ee. Publication is owner-confirmed; the existing automated HIL records remain incomplete and are not relabeled as passed. The installer page remains authoritative for what is active now.