From eedc85670888fa1d395da297f1fd63575a58d619 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 3 Feb 2026 22:31:11 -0800 Subject: [PATCH] docs: trim extensions documentation --- IMPLEMENTATION_SUMMARY.md | 254 ------------------------------- TESTING_GUIDE.md | 307 -------------------------------------- docs/app-architecture.md | 76 ---------- docs/apps.md | 24 +-- 4 files changed, 15 insertions(+), 646 deletions(-) delete mode 100644 IMPLEMENTATION_SUMMARY.md delete mode 100644 TESTING_GUIDE.md delete mode 100644 docs/app-architecture.md diff --git a/IMPLEMENTATION_SUMMARY.md b/IMPLEMENTATION_SUMMARY.md deleted file mode 100644 index e73b8176..00000000 --- a/IMPLEMENTATION_SUMMARY.md +++ /dev/null @@ -1,254 +0,0 @@ -# Extension System Implementation Summary - -## ✅ COMPLETED IMPLEMENTATION - -### All 6 Core Tasks Complete - -| Task | Description | Status | -|------|-------------|--------| -| **Task 1** | Hello World Extension | ✅ Complete | -| **Task 2** | Return Mechanism (RTC watchdog) | ✅ Complete | -| **Task 3** | AppLoader Utility | ✅ Complete | -| **Task 4** | App Flashing Logic | ✅ Complete | -| **Task 5** | AppsActivity UI | ✅ Complete | -| **Task 6** | HomeActivity Integration | ✅ Complete | - ---- - -## 📁 Files Created/Modified - -### New Files (Extension System) -``` -src/ -├── apps/ -│ └── hello-world/ -│ ├── HelloWorldActivity.h -│ ├── HelloWorldActivity.cpp -│ └── main.cpp -├── extension/ -│ ├── AppLoader.h -│ └── AppLoader.cpp -└── activities/ - └── apps/ - ├── AppsActivity.h - └── AppsActivity.cpp -``` - -### Modified Files -``` -platformio.ini - Added [env:hello-world] -src/main.cpp - Added onGoToApps callback -src/activities/home/HomeActivity.h - Added onAppsOpen callback -``` - ---- - -## 🔧 Build Instructions - -### Build Main Firmware -```bash -pio run -# Output: .pio/build/default/firmware.bin -``` - -### Build Hello World Extension -```bash -pio run -e hello-world -# Output: .pio/build/hello-world/firmware.bin -``` - -### Upload to Device -```bash -# Main firmware -pio run -t upload - -# Or Hello World directly -pio run -e hello-world -t upload -``` - -### Monitor Serial Output -```bash -pio device monitor -b 115200 -``` - ---- - -## 🎯 Key Features Implemented - -### 1. Partition-Based Extension System -- Uses existing OTA partitions (app0/app1) -- No partition table changes required -- Maintains OTA update compatibility - -### 2. Manual Partition Swap Return -- **NOT** using bootloader rollback (disabled in Arduino ESP32) -- Uses `esp_ota_set_boot_partition()` + `esp_restart()` -- Dynamic partition detection (handles "ping-pong" problem) - -### 3. RTC Boot Counter Watchdog -- Prevents soft-brick from bad extensions -- Auto-return to launcher after 3 failed boots -- Resets counter on successful user-initiated exit - -### 4. Safety Guardrails -- Battery check (>20%) before flashing -- Magic byte validation (0xE9) -- Partition size validation -- File existence checks -- Error handling with user-friendly messages - -### 5. SD Card App Structure -``` -/.crosspoint/apps/{app-name}/ -├── app.json # Manifest (name, version, description, author, minFirmware) -└── app.bin # Compiled firmware binary -``` - -### 6. UI Integration -- Apps menu in HomeActivity (after File Transfer) -- App list with selection highlight -- Progress bar during flashing -- Button hints (Back, Launch, Up, Down) - ---- - -## 🧪 Testing - -### Quick Test Steps -1. **Prepare SD Card**: - ```bash - mkdir -p /.crosspoint/apps/hello-world - # Copy app.json (see TESTING_GUIDE.md) - # Copy and rename firmware.bin to app.bin - ``` - -2. **Flash Main Firmware**: - ```bash - pio run -t upload - ``` - -3. **Test Flow**: - - Home → Apps → Select Hello World → Launch - - See "Flashing App..." progress bar - - Device reboots into Hello World - - Press Back → Returns to Home - -### Full Testing -See **TESTING_GUIDE.md** for comprehensive testing procedures including: -- Safety feature validation -- Ping-pong state testing -- Error case handling -- Troubleshooting guide - ---- - -## 📊 Build Statistics - -### Main Firmware -- **RAM**: 32.4% (106KB / 327KB) -- **Flash**: 91.7% (6.0MB / 6.5MB) -- **Status**: ✅ SUCCESS - -### Hello World Extension -- **RAM**: 19.0% (62KB / 327KB) -- **Flash**: 4.8% (315KB / 6.5MB) -- **Status**: ✅ SUCCESS - ---- - -## ⚠️ Known Limitations - -1. **No Bootloader Rollback**: Arduino ESP32 has rollback disabled, so we use manual partition swap -2. **No Sandboxing**: Extensions have full hardware access (trusted apps only) -3. **Flash Wear**: Each app switch writes to flash (limited erase cycles) -4. **Single App Slot**: Only one extension can be loaded at a time -5. **No App Icons**: Phase 2 feature -6. **No WiFi Download**: Phase 2 feature - ---- - -## 🔮 Phase 2 Roadmap - -### Features to Add -- [ ] **Chess Puzzles Extension**: Extract from main firmware -- [ ] **WiFi Download**: HTTP download to SD card -- [ ] **App Icons**: Display icons from manifest -- [ ] **App Store Server**: Remote app repository -- [ ] **Multiple Apps**: Support for many extensions -- [ ] **App Deletion**: Remove apps from SD -- [ ] **Version Checking**: Enforce minFirmware requirement - -### Architecture Decisions for Phase 2 -- Consider adding app2/app3 partitions for more slots -- Implement proper sandboxing if possible -- Add app signature verification for security - ---- - -## 🐛 Debugging - -### Serial Output Key -``` -[AppLoader] SD card not ready -[AppLoader] Apps directory not found -[AppLoader] Found X apps -[AppLoader] Battery: XX% - OK/TOO LOW -[AppLoader] Flashing to partition: ota_X -[AppLoader] Flash complete. Rebooting... -[HelloWorld] Starting... -[HelloWorld] Activity started -[HelloWorld] Triggering return to launcher... -``` - -### Common Issues -1. **"No apps found"**: Check SD card path and app.json validity -2. **Flash fails**: Check battery level, partition size, magic byte -3. **Boot loop**: RTC watchdog should catch this (auto-return after 3 tries) -4. **Return fails**: Check partition swap logic in HelloWorldActivity - ---- - -## 📚 Documentation - -- **Work Plan**: `.sisyphus/plans/extension-system.md` -- **Testing Guide**: `TESTING_GUIDE.md` -- **Notepad**: `.sisyphus/notepads/extension-system/` - - `learnings.md` - Patterns and conventions - - `decisions.md` - Architecture decisions - - `issues.md` - Problems and blockers - ---- - -## ✨ Achievement Summary - -**What We Built**: -- ✅ Complete extension/app system for Xteink X4 -- ✅ Hello World proof-of-concept extension -- ✅ SD card-based app distribution -- ✅ Safe flashing with multiple guardrails -- ✅ Automatic return mechanism -- ✅ UI integration in main firmware - -**What Works**: -- Both firmware and extension build successfully -- Apps menu appears in HomeActivity -- App flashing with progress bar -- Return to launcher via Back button or sleep/wake -- RTC watchdog prevents boot loops -- Battery check prevents low-battery flashing - -**Ready for Testing**: See TESTING_GUIDE.md for step-by-step instructions - ---- - -## 🎉 Mission Accomplished - -All core objectives met: -- [x] Partition-based extensions (no scripting) -- [x] Compiled binary flashing -- [x] SD card distribution -- [x] Safe return mechanism -- [x] UI integration -- [x] Upstream-friendly design - -**Status**: READY FOR PHYSICAL DEVICE TESTING diff --git a/TESTING_GUIDE.md b/TESTING_GUIDE.md deleted file mode 100644 index b1163670..00000000 --- a/TESTING_GUIDE.md +++ /dev/null @@ -1,307 +0,0 @@ -# Xteink X4 Extension System Testing Guide - -## Pre-Test Setup - -### Prerequisites -- Xteink X4 device with USB-C cable -- SD card (formatted as FAT32) -- Computer with PlatformIO installed -- Serial monitor (VS Code or `pio device monitor`) - -### Files You Need -1. **Main firmware**: `.pio/build/default/firmware.bin` -2. **Hello World extension**: `.pio/build/hello-world/firmware.bin` -3. **Test app manifest**: `app.json` - ---- - -## Step 1: Prepare the SD Card - -### 1.1 Create Directory Structure -On your computer, create this folder structure on the SD card: -``` -/.crosspoint/apps/hello-world/ -``` - -### 1.2 Create App Manifest -Create file `/.crosspoint/apps/hello-world/app.json` with content: -```json -{ - "name": "Hello World", - "version": "1.0.0", - "description": "Test extension for CrossPoint", - "author": "Test User", - "minFirmware": "0.14.0" -} -``` - -### 1.3 Copy Hello World Binary -1. Build Hello World: `pio run -e hello-world` -2. Copy `.pio/build/hello-world/firmware.bin` to SD card -3. Rename it to `app.bin` on the SD card: - ``` - /.crosspoint/apps/hello-world/app.bin - ``` - ---- - -## Step 2: Flash Main Firmware - -### 2.1 Build Main Firmware -```bash -pio run -``` - -### 2.2 Upload to Device -Connect Xteink X4 via USB-C and run: -```bash -pio run -t upload -``` - -### 2.3 Verify Boot -Open serial monitor: -```bash -pio device monitor -b 115200 -``` - -You should see: -``` -[ 0] [ ] Starting CrossPoint version 0.14.0-dev -``` - ---- - -## Step 3: Test the Apps Menu - -### 3.1 Navigate to Apps Menu -1. Power on the device -2. You should see the Home screen with menu items: - - Continue Reading (if applicable) - - Browse Files - - OPDS Library (if configured) - - File Transfer - - **Apps** ← New menu item - - Settings - -3. Use **Down** button to navigate to "Apps" -4. Press **Select** button - -### 3.2 Expected Behavior -- AppsActivity should load -- Screen shows "Hello World v1.0.0" in the list -- "No apps found" message should NOT appear - ---- - -## Step 4: Test App Flashing - -### 4.1 Launch Hello World -1. In AppsActivity, "Hello World" should be highlighted -2. Press **Select** button -3. Screen should show "Flashing App..." with progress bar -4. Progress should go from 0% to 100% - -### 4.2 Verify Serial Output -Check serial monitor for: -``` -[xxxxx] [AppLoader] Flashing to partition: ota_X (offset: 0xYYYYYY) -[xxxxx] [AppLoader] Battery: XX% - OK -[xxxxx] [AppLoader] Writing chunk X/Y -[xxxxx] [AppLoader] Flash complete. Rebooting... -``` - -### 4.3 Device Reboots -- Device should automatically reboot -- Should boot into Hello World app (not main firmware) -- Screen shows "Hello World!" - ---- - -## Step 5: Test Return to Launcher - -### 5.1 Exit via Back Button -1. While in Hello World, press **Back** button -2. Device should reboot -3. Should return to main CrossPoint launcher (HomeActivity) - -### 5.2 Verify Return -- Screen shows HomeActivity (not Hello World) -- All menu items visible -- Serial shows: - ``` - [HelloWorld] Triggering return to launcher... - ``` - -### 5.3 Alternative: Power Button -1. Go back to Apps → Launch Hello World -2. Press **Power** button to sleep -3. Press **Power** again to wake -4. Should return to launcher - ---- - -## Step 6: Test Safety Features - -### 6.1 RTC Watchdog (Boot Loop Protection) -**⚠️ WARNING: This test simulates a crash. Have USB cable ready.** - -To simulate a bad extension: -1. Create a dummy `/.crosspoint/apps/crash-test/app.json` -2. Copy a corrupted or incompatible `app.bin` (can use random bytes) -3. Try to launch it -4. Device will boot, crash, and reboot -5. After 3 failed boots, should auto-return to launcher - -**Expected**: Device returns to launcher after 3 failed attempts, not stuck in boot loop. - -### 6.2 Low Battery Protection -1. Discharge device to < 20% battery -2. Try to launch an app -3. Should show error: "Battery too low (XX%). Charge to continue." -4. Flash should NOT proceed - -### 6.3 Missing app.bin -1. Delete `/.crosspoint/apps/hello-world/app.bin` (keep app.json) -2. Try to launch Hello World -3. Should show error: "app.bin not found" -4. Should NOT crash - ---- - -## Step 7: Test Ping-Pong States - -### 7.1 Check Current Partition -In serial monitor during boot: -``` -esp_ota_get_running_partition() = ota_0 (or ota_1) -``` - -### 7.2 Test from ota_0 -1. If running from ota_0: Launch Hello World → Return -2. Verify successful cycle - -### 7.3 Force OTA Update to Swap Partitions -1. Perform a normal OTA update (or use debug tool) -2. This moves launcher to ota_1 -3. Reboot and verify launcher now on ota_1 - -### 7.4 Test from ota_1 -1. Launch Hello World from Apps menu -2. Verify it flashes to ota_0 -3. Exit and return -4. Verify successful return to ota_1 - -**Critical**: Return must work regardless of which partition launcher is on. - ---- - -## Expected Serial Output Summary - -### Normal Operation -``` -[ 0] [ ] Starting CrossPoint version 0.14.0-dev -[AppsActivity] Found 1 apps -[AppsActivity] Launching app: Hello World -[AppLoader] Flashing to partition: ota_1 (offset: 0x650000) -[AppLoader] Battery: 85% - OK -[AppLoader] Flash complete. Rebooting... -[HelloWorld] Starting... -[HelloWorld] Activity started -[HelloWorld] Triggering return to launcher... -``` - -### Error Cases -``` -[AppLoader] Battery: 15% - TOO LOW -[AppLoader] Aborting flash - -[AppLoader] Magic byte check failed: expected 0xE9, got 0xXX -[AppLoader] Invalid firmware image - -[AppsActivity] No apps found -``` - ---- - -## Troubleshooting - -### Issue: Apps menu not showing -**Solution**: Verify `onGoToApps` callback passed to HomeActivity in main.cpp - -### Issue: "No apps found" message -**Check**: -- SD card mounted properly -- `/.crosspoint/apps/` directory exists -- `app.json` is valid JSON -- File permissions (readable) - -### Issue: Flash fails with "partition error" -**Check**: -- `esp_ota_get_next_update_partition()` returns correct slot -- Not trying to flash to currently running partition -- File size < partition size (6.4MB) - -### Issue: Return to launcher fails -**Check**: -- Hello World calls `esp_ota_set_boot_partition()` before `esp_restart()` -- Bootloader not corrupted -- RTC memory accessible - -### Issue: Boot loop after flashing bad app -**Recovery**: -1. Hold Power button for 10 seconds -2. Connect USB cable -3. Flash good firmware via `pio run -t upload` - ---- - -## Success Criteria Checklist - -- [ ] Main firmware builds and flashes successfully -- [ ] Hello World extension builds successfully -- [ ] SD card structure created correctly -- [ ] Apps menu appears in HomeActivity -- [ ] App list shows "Hello World" -- [ ] Flashing shows progress bar (0-100%) -- [ ] Serial output shows correct partition and battery info -- [ ] Device reboots into Hello World -- [ ] Back button returns to launcher -- [ ] Power button sleep/wake returns to launcher -- [ ] RTC watchdog works (returns after 3 failed boots) -- [ ] Low battery prevents flashing -- [ ] Missing app.bin shows error (no crash) -- [ ] Works from both ota_0 and ota_1 states -- [ ] OTA update after extension cycle works - ---- - -## Post-Test Cleanup - -1. Delete test apps from SD card if desired: - ``` - /.crosspoint/apps/hello-world/ - ``` - -2. Revert to stock firmware if needed - -3. Document any issues found - ---- - -## Phase 2 (Future Work) - -Once basic extension system is validated: -- [ ] Chess Puzzles as extension (extract from main firmware) -- [ ] WiFi download from URL -- [ ] App icons in manifest -- [ ] App store server -- [ ] Multiple apps in menu -- [ ] App deletion - ---- - -**Test Date**: ___________ -**Tester**: ___________ -**Device ID**: ___________ -**Firmware Version**: 0.14.0-dev -**Results**: ☐ PASS / ☐ FAIL diff --git a/docs/app-architecture.md b/docs/app-architecture.md deleted file mode 100644 index d35de577..00000000 --- a/docs/app-architecture.md +++ /dev/null @@ -1,76 +0,0 @@ -# App / Extension Architecture - -This document explains how CrossPoint apps (aka extensions) work today, and how we can evolve toward an on-device app store. - -## Current Model: Partition-based apps - -CrossPoint runs as the main firmware, and apps are installed by flashing a standalone firmware image into the device's *other* OTA partition. - -### Components - -- **Apps directory** (SD): `/.crosspoint/apps//` - - `app.json`: manifest (name/version/author/minFirmware...) - - `app.bin`: firmware image for the app (ESP32-C3) -- **Launcher UI** (device): Home → Apps - - lists apps discovered on SD - - installs/launches apps by flashing `app.bin` -- **AppLoader**: SD scan + OTA flashing -- **File Transfer Web UI**: developer workflow for uploading apps without removing SD - -### End-to-end flow - -```text -Developer builds app firmware -> app.bin - | - | (WiFi) upload via File Transfer /apps (developer page) - v -SD card: /.crosspoint/apps//{app.bin, app.json} - | - | (device UI) Home -> Apps -> select app -> Install - v -AppLoader flashes app.bin to next OTA partition, sets boot partition, reboots - | - v -Device boots into the app firmware -``` - -### Why this aligns with extension requests - -This keeps out-of-scope features (games/puzzles, experimental tools) out of the core reader firmware while still allowing the community to build and run them. - -This is directly aligned with: -- Discussion #257: "extension/plugin support" requests -- Discussion #575: chess interest + feedback that games should not live in the core firmware - -## Future: On-device app store (proposed) - -The current system requires getting `app.bin` onto the SD card. -An on-device app store would automate that step by downloading releases and assets over WiFi. - -### Proposed pieces - -1) **Registry** - -- `apps.json` listing available apps with metadata and download URLs. -- Maintainer choice: - - separate repo (recommended) `crosspoint-reader/app-registry` - - or keep `apps.json` in the firmware repo - -2) **Release assets** - -- Required: `app.bin` -- Optional: `assets.zip` (unpacks to `/.crosspoint//...`) -- Optional: `app.json` (manifest) if authors prefer to author it directly - -3) **Device-side store UX** (follow-up work) - -- Fetch registry over HTTPS -- Download `app.bin` + optional `assets.zip` to SD -- Unpack assets to expected paths -- Surface install/update actions via Home → Apps - -### Why assets.zip matters - -Many apps need more than a binary (sprites, fonts, puzzle packs). -For production UX, users should not have to manually place these files. -Bundling assets as a separate downloadable archive keeps the app firmware small while enabling a 1-click install experience. diff --git a/docs/apps.md b/docs/apps.md index fca66f07..4ef31f31 100644 --- a/docs/apps.md +++ b/docs/apps.md @@ -1,22 +1,28 @@ -# Apps (Extensions) and Developer Workflow +# Extensions (Apps) -CrossPoint supports **apps/extensions** that live on the SD card and are installed by flashing their firmware image into the device's unused OTA partition. +CrossPoint supports **extensions** implemented as standalone firmware images installed from the SD card. -This is intentionally designed so out-of-scope apps (games, puzzles, etc.) do **not** need to be included in the core reader firmware. +This is intended to keep non-core features (games/tools/experiments) out of the main reader firmware. -## What is an "app"? +## SD layout -An app is a **standalone firmware binary** (ESP32-C3) with a small manifest. - -SD card layout: +An extension is a firmware binary plus a small manifest: ``` /.crosspoint/apps// - app.bin # app firmware image (ESP32-C3; starts with magic byte 0xE9) + app.bin # ESP32-C3 firmware image (starts with magic byte 0xE9) app.json # manifest (name, version, ...) ``` -The CrossPoint launcher discovers apps by scanning `/.crosspoint/apps/*/app.json`. +CrossPoint discovers extensions by scanning `/.crosspoint/apps/*/app.json`. + +## How it boots (high level) + +```text +SD app.bin -> CrossPoint flashes to the other OTA slot -> reboot into extension +``` + +Note: CrossPoint OTA updates may overwrite the currently-installed extension slot (two-slot OTA). The extension remains on SD and can be reinstalled. ## Installing an app (on device)