Frame-based binary protocol for reliable device communication with checksum validation and command dispatch.
Last updated: August 15, 2026
[0xA5][0x5A] Magic sync (2 bytes)
[VER] Version (1 byte) - currently 1
[TYPE] Message type (1 byte)
1 = request, 2 = response_ok, 3 = response_err
[FLAGS] Bitfield (1 byte) - usually 0
[LEN_HI][LEN_LO] Payload length, big-endian (2 bytes)
[PAYLOAD...] Command data (variable)
[CKSUM_HI][CKSUM_LO] Checksum - sum of VER+TYPE+FLAGS+LEN+PAYLOAD[CMD_ID_LO][CMD_ID_HI] Command ID, little-endian (2 bytes)
0x0001 = ping, 0x0004 = bootloader, etc.
[PKT_TYPE] Packet type (1 byte)
1 = request, 2 = ok response, 3 = error response
[META] Metadata (1 byte) - bit 0 = ack requested
[DATA...] Command-specific data (variable)from app.utils.device_serial.byte_protocol import encode_frame, TYPE_REQUEST
payload = b"\x01\x00\x01\x00" # Raw binary command
frame = encode_frame(TYPE_REQUEST, payload)
# Result: b'\xa5Z\x01\x01\x00\x00\x04\x01\x00\x01\x00\x04\x06'from app.utils.device_serial.byte_protocol import decode_frame
response = b'\xa5Z\x02\x02\x00...'
decoded = decode_frame(response)
if decoded:
print(f"Type: {decoded.msg_type}, Payload: {decoded.payload}")import serial
from app.utils.device_serial.byte_protocol import encode_frame, TYPE_REQUEST
from app.utils.device_serial.command_codec import encode_request
# Open serial to Pico
ser = serial.Serial('/dev/ttyACM0', 115200, timeout=1)
# Build PING command
payload = encode_request({'method': 'ping'})
frame = encode_frame(TYPE_REQUEST, payload)
print(f"Sending PING: {frame.hex()}")
ser.write(frame)
# Read response
response = ser.read(100)
print(f"Response: {response.hex()}")
ser.close()import serial
from app.utils.device_serial.byte_protocol import encode_frame, TYPE_REQUEST
from app.utils.device_serial.command_codec import encode_request
import time
ser = serial.Serial('/dev/ttyACM0', 115200, timeout=1)
# Send BOOTLOADER command
payload = encode_request({'method': 'reboot.bootloader'})
frame = encode_frame(TYPE_REQUEST, payload)
print(f"Sending BOOTLOADER: {frame.hex()}")
ser.write(frame)
# Device will disconnect/reboot (no response expected)
time.sleep(1)
# Check if RPI-RP2 mount appears
import os
time.sleep(2)
bootsel_mounts = [d for d in os.listdir('/media/user') if 'RPI' in d.upper()]
if bootsel_mounts:
print(f"✅ BOOTSEL successful! Mount: {bootsel_mounts[0]}")
else:
print("❌ No BOOTSEL mount detected")
ser.close()| Constant | Value | Use |
|---|---|---|
| MAGIC_0 | 0xA5 | Frame synchronization |
| MAGIC_1 | 0x5A | Frame synchronization |
| VERSION | 1 | Protocol version |
| TYPE_REQUEST | 1 | Client → Device |
| TYPE_RESPONSE | 2 | Device → Client (success) |
| CMD_PING | 0x0001 | Health check |
| CMD_DRIVER_INFO | 0x0002 | List drivers |
| CMD_DRIVER_CALL | 0x0003 | Execute RPC |
| CMD_REBOOT_BOOTLOADER | 0x0004 | Reboot to BOOTSEL |
pico_tools/flash_pico.pyHardware flashing toolfirmware/SerialLookout/CommandParser.cppPico firmware main loopfirmware/drivers/src/protocol.cFrame encoder/decoderserver/backend/app/utils/device_serial/byte_protocol.pyServer frame codecdmesg | tail -20screen /dev/ttyACM0 115200