Files
qemu-xteink/.pi/skills/test-xteink-firmware/SKILL.md
T

3.8 KiB

name, description
name description
test-xteink-firmware Build and interactively test Xteink ESP32-C3 firmware in the native emulator. Use when validating firmware UI, buttons, screenshots, serial output, SD behavior, or networking.

Test Xteink Firmware

Overview

Build firmware for an Xteink device, boot it in the native emulator, and validate behavior through serial logs, physical controls, screenshots, SD state, and network access.

Prerequisites

Point XTEINK_QEMU_REPO at a prepared QEMU checkout containing dist/qemu-native:

export XTEINK_QEMU_REPO=${XTEINK_QEMU_REPO:-../qemu}
export XTEINK_EMU_STATE=/tmp/xteink-firmware-$UID
export XTEINK_EMU_SD=/tmp/xteink-firmware-$UID.img

The emulator exits with setup instructions when its native QEMU distribution is missing.

Workflow

  1. Inspect the firmware project and use its documented build command. Locate the resulting ESP32-C3 application binary; for PlatformIO this is commonly:

    pio run
    export XTEINK_FIRMWARE=.pio/build/default/firmware.bin
    
  2. Create a persistent FAT32 SD image once, unless the test requires a fresh card:

    truncate -s 64M "$XTEINK_EMU_SD"
    mkfs.fat -F 32 "$XTEINK_EMU_SD"
    
  3. Start a clean emulator process while preserving SD contents:

    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-emu.py" stop \
      --state-dir "$XTEINK_EMU_STATE" || true
    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-emu.py" start \
      --state-dir "$XTEINK_EMU_STATE" \
      --firmware "$XTEINK_FIRMWARE" \
      --sdcard "$XTEINK_EMU_SD"
    

    start simulates a two-second power-button hold for cold boot. Override --power-hold-ms when testing power behavior.

  4. Observe serial behavior with either a persistent regex cursor or the raw log:

    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-emu.py" wait \
      --state-dir "$XTEINK_EMU_STATE" --timeout 30 --match 'pattern'
    tail -f "$XTEINK_EMU_STATE/serial.log"
    
  5. Drive the physical controls:

    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-emu.py" button \
      --state-dir "$XTEINK_EMU_STATE" bottom-2
    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-emu.py" button \
      --state-dir "$XTEINK_EMU_STATE" power --down
    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-emu.py" button \
      --state-dir "$XTEINK_EMU_STATE" power --up
    

    Available buttons are left, right, bottom-1 through bottom-4, and power. Use the labels rendered by the current screen as the authoritative mapping. Allow the e-ink panel to refresh after state-changing input.

  6. Capture and inspect the screen after meaningful transitions:

    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-emu.py" screenshot \
      --state-dir "$XTEINK_EMU_STATE" --output /tmp/xteink-screen.png
    
  7. Enter text when the firmware's on-screen keyboard is focused:

    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-type-keyboard.py" \
      "$XTEINK_EMU_STATE" normal 'Example'
    uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-type-keyboard.py" \
      "$XTEINK_EMU_STATE" url 'https://example.com'
    
  8. For network tests, connect the firmware to the single open Wi-Fi network named qemu, then validate the feature's observable result.

Diagnose Failures

  • Firmware serial output: $XTEINK_EMU_STATE/serial.log
  • Emulator output: $XTEINK_EMU_STATE/qemu.log
  • Assembled flash image: $XTEINK_EMU_STATE/flash.bin
  • Resolve crash addresses against the exact ELF produced with the tested binary, using the project's RISC-V addr2line tool.
  • Preserve the SD image when reproducing persistence bugs; replace it when testing first-boot behavior.

Cleanup

uv run --script "$XTEINK_QEMU_REPO/scripts/xteink-emu.py" stop \
  --state-dir "$XTEINK_EMU_STATE"