Files
tactility_apps/.claude/skills/tactility-app-development/references/symbols.md
T
Adolfo Reyna 479a448900
Main / Build (AudioTest) (push) Has been cancelled
Main / Build (BibleVerse) (push) Has been cancelled
Main / Build (BookPlayer) (push) Has been cancelled
Main / Build (Brainfuck) (push) Has been cancelled
Main / Build (Breakout) (push) Has been cancelled
Main / Build (Calculator) (push) Has been cancelled
Main / Build (Diceware) (push) Has been cancelled
Main / Build (EpubReader) (push) Has been cancelled
Main / Build (EspNowBridge) (push) Has been cancelled
Main / Build (GPIO) (push) Has been cancelled
Main / Build (GameBoy) (push) Has been cancelled
Main / Build (GraphicsDemo) (push) Has been cancelled
Main / Build (HelloWorld) (push) Has been cancelled
Main / Build (M5UnitTest) (push) Has been cancelled
Main / Build (Magic8Ball) (push) Has been cancelled
Main / Build (McpScreen) (push) Has been cancelled
Main / Build (MediaKeys) (push) Has been cancelled
Main / Build (Mp3Player) (push) Has been cancelled
Main / Build (MystifyDemo) (push) Has been cancelled
Main / Build (PocketDungeon) (push) Has been cancelled
Main / Build (ReynaBot) (push) Has been cancelled
Main / Build (RobotArm) (push) Has been cancelled
Main / Build (SerialConsole) (push) Has been cancelled
Main / Build (Snake) (push) Has been cancelled
Main / Build (TamaTac) (push) Has been cancelled
Main / Build (TodoList) (push) Has been cancelled
Main / Build (TwoEleven) (push) Has been cancelled
Main / Build (VoiceRecorder) (push) Has been cancelled
Main / Bundle (push) Has been cancelled
Main / PublishApps (push) Has been cancelled
docs(tactility-app-dev): note device_get_* not exported; use device_find_* legacy API
Flashed 0.8.0-dev firmware exports device_find_* but not the newer device_get_*
out-param API. verify_symbols.py compares vs local firmware source and can pass
even when the flashed firmware differs — confirm on-device via serial
(/dev/cu.usbmodem*, 115200). Record the local extern-declare workaround.
2026-08-19 21:19:28 -04:00

6.5 KiB

Symbol Check — BibleVerse session (updated July 12 v5 pretty font)

Tool: undefined symbols vs firmware exports

import pathlib, re, subprocess
elf = pathlib.Path("Apps/BibleVerse/build/cmake-build-esp32s3/BibleVerse.app.elf")
r = subprocess.run(["zsh","-c", f"source ~/esp/esp-idf/export.sh >/dev/null 2>&1; xtensa-esp32s3-elf-nm -D {elf}"], capture_output=True, text=True)
undef = [l.split()[-1] for l in r.stdout.splitlines() if len(l.split())>=2 and l.split()[-2]=='U']

pat = re.compile(r'(?:ESP_ELFSYM_EXPORT|DEFINE_MODULE_SYMBOL)\s*\(\s*([A-Za-z0-9_]+)\s*\)')
exp=set()
for fp in pathlib.Path("../firmware").rglob("*.*"):
  if 'build' in str(fp): continue
  if fp.suffix not in ('.c','.h','.cpp'): continue
  try: exp.update(m.group(1) for m in pat.finditer(fp.read_text(errors='ignore')))
  except: pass
missing = [s for s in undef if s not in exp]
print(f"undef {len(undef)} missing {missing}")

Session results

  • Before fix: undef 68, missing ['lv_font_montserrat_14'] — source used &lv_font_montserrat_14.
  • After lvgl_get_text_font(FONT_SIZE_SMALL): undef 68, missing [] ✅
  • Editorial v4: 0 missing, anim symbols ok, app 4413440 bytes, heap 54KB stable on .129
  • v5 pretty font: Georgia Italic embedded C 26/22/20/18/16 + regular 24 via lv_font_conv, 315KB .rodata in PSRAM, 0 missing, app 4.3MB, heap 47539 free largest 20480 psram 4810944 stable, screenshot 5336 bytes Habakkuk 1:17 serif italic editorial.
  • v6 final beautiful 2142871: 0 missing, undef 0, app 4.3M, heap 46215-47591 free largest 20480 psram 4810396 stable, screenshots 8683 menu visible (top Zeph 1:3 / 31094 + bottom pills) + 6882 immersive hidden, lift -7 15px corrected from -22 30px per user, black bar fixed. Gotcha lv_timer_t user_data field incomplete → t->user_data invalid → must use lv_timer_get_user_data(t) + lv_timer_set_user_data (exports 372/373/382/388). Checked grep timer symbols.c. Timer used for chrome auto-hide 10s + book browser anim.

Known missing table

Symbol Status Workaround
lv_font_montserrat_14/18/24 Not exported lvgl_get_text_font(FONT_SIZE_SMALL/DEFAULT/LARGE) OR embedded C serif via lv_font_conv → see pretty-font.md
LV_SYMBOL_STAR May be absent Use LV_SYMBOL_OK, LV_SYMBOL_DUMMY
xTaskGetCurrentTaskHandle Not exported Avoid task identity check; release lock
lv_image_set_rotation Not exported lv_obj_set_style_transform_rotation(obj, deg*10, 0)
cJSON, esp_websocket_client Static Vendor source or raw lwip_socket APIs

New missing from v2/v3/v4/v5 UI passes

  • device_get_by_name, device_get_first_by_type (out-param API) → Not exported on flashed 0.8.0-dev (verified via serial on .129: E ELF: Can't find symbol device_get_by_name). The firmware exports the legacy device_find_by_name / device_find_first_by_type instead. Gotcha: newer SDK/CDN headers declare only device_get_* (so device_find_* fails to compile), but the flashed firmware only exports device_find_* (so device_get_* fails at load). Fix: call the exported legacy device_find_* and declare them locally in the app source since the SDK header dropped them:
    extern struct Device* device_find_by_name(const char* name);
    extern struct Device* device_find_first_by_type(const struct DeviceType* type);
    
    Verify the ACTUAL load on-device via serial (/dev/cu.usbmodem*, 115200) — verify_symbols.py compares against local firmware source and can report 0 missing even when the flashed firmware's export table differs.
  • lv_obj_set_style_bg_grad_color/dir/stop → Not exported 0.8.0-dev. Gradient fails missing symbol. Use solid 0x0E0E14.
  • LV_OPA_95 → Not defined (only 0/10/20/30/40/50/60/70/80/90/100/COVER/TRANSP). Use COVER or 90.
  • lv_arc_create, lv_arc_set_range/value/bg_angles, lv_arc_get_value → Not exported on 0.7.0-dev, added dff93cb6 Add lv_arc.h symbols (#496) after 0.7 release. Symptom blue modal Error / Application failed to start: missing symbol / OK, heap healthy ~31KB not OOM. Fix horizontal slide using lv_slider_create + lv_indev_get_point/active. See book-browser.md.
  • lv_roller_create → Not exported 0.7 nor 0.8.
  • lv_indev_get_point/active, lv_slider_create/range/value/set_value → Exported since 0.6 safe.
  • lv_anim_init, set_var/values/duration/exec_cb/path_cb/start, path_ease_out/linear/ease_in, path_ease_in_out → Exported since 0.6 safe (checked lines 435-446). Used for editorial fade 220/300ms. Safe for 0.7/0.8 fleet.
  • lv_binfont_create/destroy → Exported 0.8 but VFS path fragile — tt_app_get_assets_path returns void, not bool (check buf[0]!='\0'). Prefer embedded C fonts via LV_FONT_DECLARE — lives in PSRAM (315KB .rodata), no FS needed. See pretty-font.md. Old .fnt bins 52KB still bundled in assets/fonts/ but not used.
  • lv_font_t embedded C — no symbol needed, static const.

Heap OOM vs missing-symbol distinction

  • OOM: heap free 275B total 310KB largest_block 23, install 500 failed to create temp directory, screenshot 500. Cause 66-button browser 132-264 objs. Fix ~10 obj browser.
  • Missing symbol: heap free 31779 largest 12288 healthy, install 200 ok, run 200 ok, but app shows blue Error missing symbol dialog, screenshot 200 2755. Fix check symbols.c.

Font scaling v4/v5

Only 3 sizes via lvgl_get_text_font() fallback, but v5 uses embedded serif as primary:

size_t len = strlen(verse);
enum LvglFontSize fs; int line_sp, pad_v, pad_h;
if (len < 40)      { fs=FONT_SIZE_LARGE;   line_sp=14; pad_v=10; pad_h=28; letter_sp=1; } // v4 tightened
else if (len <100) { fs=FONT_SIZE_LARGE;   line_sp=10; pad_v=8; pad_h=24; }
else if (len <200) { fs=FONT_SIZE_DEFAULT; line_sp=8;  pad_v=6; pad_h=20; }
else if (len <350) { fs=FONT_SIZE_SMALL;   line_sp=6;  pad_v=4; pad_h=16; }
else               { fs=FONT_SIZE_SMALL;   line_sp=4;  pad_v=2; pad_h=12; } // Esther 492c

// v5: resolve to embedded Georgia Italic 26/20/16 else fallback
lv_obj_set_style_text_font(lbl_verse, resolve_verse_font(ctx, fs), 0);

Proven .112 Genesis 2:10 77c LARGE, .129 Ephesians 1:4 4138 bytes screenshot editorial warm #F2F0E8 + ref uppercase tracking 2 #9A9AA8 gap 10, v5 Habakkuk 1:17 5336 bytes serif italic editorial vision PASS.

Exported: lvgl_get_text_font, get_text_font_height, get_shared_icon_font, set_style_text_font, timer_create, label_set_text, text_line_space, pad_*, text_opa, anim_*, LV_FONT_DECLARE (macro, not symbol).

CI: fail if missing>0, heap stable >40KB with fonts.