Memory Management

Partition table strategy for lynx-v4 flash storage. Tower owns custom partitions for pairing and keymaps. Cat uses espflash defaults.

Design Philosophy

Asymmetric by nature:

  • Tower stores state (pairing MACs, RMK keymaps)
  • Cat is stateless (capture and transmit only)

Partition table lives where it's used. Tower owns partitions.csv because tower uses custom partitions. Cat doesn't need persistence, so it doesn't need custom partitions.

Tower Partition Layout

File: /firmware/tower/partitions.csv

ESP32-S3 Flash (8MB)
┌────────────────────────────────────────────────┐
│ Offset     Size      Partition      Purpose    │
├────────────────────────────────────────────────┤
│ 0x0000     32KB      (bootloader)   System     │
│ 0x8000     4KB       (partition tbl) System    │
│ 0x9000     20KB      nvs            RMK NVS    │
│ 0xE000     8KB       otadata        OTA meta   │
│ 0x10000    3.25MB    app0           Firmware   │
│ 0x350000   4KB       pairing        Cat MACs   │
│ 0x3F0000   16KB      rmk_storage    Keymaps    │
└────────────────────────────────────────────────┘

Custom partitions:

  • pairing (4KB) - Stores paired cat MAC addresses
  • rmk_storage (16KB) - RMK/Vial keymap persistence

Both use subtype undefined (0x06) because custom subtypes cause espflash panics.

Cat Uses Defaults

Cat firmware uses espflash's built-in partition table. No custom file needed.

Why:

  • Cat is stateless - captures input, transmits frames, stores nothing
  • Standard partitions (nvs, app0) are sufficient for esp-wifi calibration and firmware
  • No pairing storage - cat broadcasts to tower, tower stores the relationship
  • Simplicity - fewer files to manage

What cat has internally:

  • nvs - ESP-IDF system use (wifi calibration)
  • app0 - Firmware binary
  • No custom partitions

Verification

Check partition table at boot:

I (54) boot: ## Label            Usage          Type ST Offset   Length
I (60) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (67) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (73) boot:  2 app0             OTA app          00 10 00010000 00340000
I (80) boot:  3 pairing          Unknown data     01 06 00350000 00001000
I (87) boot:  4 rmk_storage      Unknown data     01 06 003f0000 00004000

Tower should show 5 partitions. Cat shows only standard partitions (nvs, otadata, app0).

Flash write verification:

🗼 💾 Erasing flash sector 0x00350000..0x00351000
🗼 💾 Erase OK, writing 20 bytes...
🗼 ✅ Flash write verified (1 devices, magic=0x43415456)

Why This Design

Semantic clarity:

  • Partition table ownership follows usage
  • Tower uses custom partitions → tower owns partitions.csv
  • Cat doesn't need persistence → no partition file

Asymmetric relationship:

  • Tower stores cat MACs in pairing partition
  • Cat doesn't store tower MAC - broadcasts to any listening tower
  • One-way storage relationship encoded in partition table structure

Simplicity for stateless devices:

  • Cat has minimal flash config surface
  • Fewer files = fewer errors
  • Default partitions are sufficient for stateless operation

Common Errors

ErrorCauseFix
OutOfBounds on towerPartition table not flashedUse ./f script (includes --partition-table)
OutOfBounds on catUsing wrong flash addressCat shouldn't write to flash (stateless)
Partitions missing at bootManual espflash without --partition-tableAlways use ./f script for tower
Data lost on rebootPartition table overwrittenReflash with ./f tower

See Also

  • docs/architecture/flash-storage.md - Deep dive on tower flash operations, Flash Manager Service, API gotchas
  • firmware/docs/pairing.md - How devices pair and MAC addresses are stored
  • firmware/tower/partitions.csv - Actual partition table definition