Skip to content

ESP32 lows: hotspot by interface, setup validation, one OTA at a time, WPA2 floor - #577

Merged
mariusandra merged 1 commit into
mainfrom
lows-esp32
Oct 18, 2026
Merged

mariusandra merged 1 commit into
mainfrom
lows-esp32

Conversation

@mariusandra

Copy link
Copy Markdown
Collaborator

The nine items in the "ESP32 — low" list of docs/embedded-todo.md. The Pico items are left for #499, which rewrites that half.

  1. Hotspot check by interface. request_from_hotspot decides by the address the connection arrived on (fos_wifi_addr_is_portal_ap()): the AP interface must be up, and the station must not hold that same address. Before, any client on a home LAN numbered 192.168.4.0/24 counted as being on the hotspot.

  2. /api/setup validation. The console and the setup form now share fos_display_panel_known() and a new fos_assets_mount_point_valid(), which has host tests. The mount-point rule:

    • absolute, 2–15 bytes, no trailing slash
    • plain characters, no . or ..
    • not under /state or /dev

    The console never validated assets_path either, so both paths check it now. A value that hasn't changed still saves, so a legacy setting can't block saving Wi-Fi.

  3. One OTA at a time. The cloud OTA task takes the backend check's lock. It waits up to 15 min, then logs ota:cloud skipped another-ota-running. The "already running" flag is set atomically.

  4. Over-long console line. It is refused once and everything up to its newline is dropped. The logic is the header-only fos_console_line.h, tested by tests/test_fos_console_line.c, which is added to the e2e-docker host-test step.

  5. Asset job queue in PSRAM. Its ~5 KB of storage now comes from fos_big_malloc (internal heap on the C3). The control block stays internal.

  6. wake_schedule in local time. It aligns using the offset the schedule already uses: the configured zone, else the provider's flat offset. The logic is fos_wake_aligned_sleep_seconds(), with host tests for UTC, +5:30 and Brussels across both 2026 DST changes. Only frames with wake_schedule on are affected.

  7. Retired OTA status fields removed: retryAttempts, requestMode, resumable, bootRequestSupported, partialRequestBytes, wifiSettleMs. Nothing on the backend, the cloud or the SPA reads them.

  8. WPA2 floor. ⚠️ WPA1-only (TKIP) networks stop connecting and log no_ap_found_in_authmode_threshold. Mixed WPA/WPA2 and WPA3 keep working.

  9. Unused USB commands deleted. Nothing calls get-asset, upload-asset or asset-op (searched the SPA, cloud-frontend, backend, e2e and docs), so they're gone, saving 1,312 B measured on S3.

Size: the S3 8 MB app is 3,119,952 B, against 3,119,824 B on main: +128 B for the batch.

Checks

  • Docker ci_build_image.sh: esp32-s3 and esp32-c3 both build with -Werror.
  • Host tests: json_guard, upload_limits, assets_path, url_guard, minisig, config_parse, schedule_catchup, cloud_contract, console_line, wake. All pass.
  • Backend: test_esp32_*.py + test_embedded_firmware.py, 115 passed.

Bench

  • Hotspot setup still works without a login when the station side is on a 192.168.4.x LAN.
  • An E1004 with wake_schedule on and a time zone set wakes on local boundaries.
  • A cloud firmware update sent while a backend OTA runs waits, then continues or logs skipped.
  • set assets_path and the setup page refuse bad mount points.
  • Asset verbs still work with the queue in PSRAM.

🤖 Generated with Claude Code

…, WPA2 floor

The nine "ESP32 — low" items of docs/embedded-todo.md:

- The hotspot check decides by the address the connection arrived on
  (fos_wifi_addr_is_portal_ap), not the peer's range, so a home LAN on
  192.168.4.0/24 no longer counts as the hotspot.
- /api/setup and the console share the panel check
  (fos_display_panel_known) and a mount-point rule
  (fos_assets_mount_point_valid, host-tested); neither checked assets_path
  before. An unchanged legacy value still saves.
- Cloud and backend OTA take one lock; the cloud task waits up to 15 min,
  then logs `ota:cloud skipped another-ota-running`.
- An over-long console line is refused once and dropped to its newline
  (fos_console_line.h, host-tested, in the e2e-docker host-test step).
- The asset job queue's storage comes from PSRAM (internal on the C3).
- wake_schedule aligns to local time from the same offset the schedule
  uses (fos_wake_aligned_sleep_seconds, host-tested across Brussels DST).
- The status JSON drops the retired OTA fields; nothing reads them.
- Wi-Fi joins WPA2-PSK and up only. WPA1-only (TKIP) networks stop
  connecting; mixed WPA/WPA2 and WPA3 keep working.
- The unused usb_api get-asset / upload-asset / asset-op go (-1,312 B).

S3 8 MB app: +128 bytes for the batch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

ESP32 firmware size

Built from da5fc6a by this run; compared with the latest release v2026.10.16.

Image This PR v2026.10.16 Δ
esp32-s3 app (OTA image) 3,119,952
86.6% of 3520K slot, 473 KB free
3,119,504 +448 (+0.0%)
esp32-s3 merged flash image 3,185,488 3,185,040 +448 (+0.0%)
esp32-s3-32mb app (OTA image) 3,119,952
75.6% of 4032K slot, 985 KB free
3,119,488 +464 (+0.0%)
esp32-s3-32mb merged flash image 3,251,024 3,250,560 +464 (+0.0%)

Breakdown by subsystem — esp32-s3

Subsystem This PR v2026.10.16 Δ
FrameOS core (Nim) 476,051 475,930 +121 (+0.0%)
QuickJS 360,285 360,285 ±0
pixie 296,919 296,959 -40 (-0.0%)
Wi-Fi stack 295,296 295,296 ±0
Nim stdlib 247,632 247,612 +20 (+0.0%)
ESP-IDF misc 181,413 181,343 +70 (+0.0%)
FrameOS apps (Nim) 181,348 181,348 ±0
Embedded font 146,358 146,358 ±0
fos_* firmware shell (C) 136,750 136,501 +249 (+0.2%)
String pool (attributed to efuse) 136,684 136,729 -45 (-0.0%)
mbedTLS + certificates 132,427 132,427 ±0
lwIP / HTTP / WebSocket 126,935 126,939 -4 (-0.0%)
libc / libm / newlib 116,263 116,263 ±0
Storage (SPIFFS / FatFS / SD / NVS) 94,068 94,068 ±0
Nim packages (chrono, zippy, chroma, qrgen, ...) 70,320 70,320 ±0
Display drivers (C) 65,029 64,962 +67 (+0.1%)
Crypto (monocypher) 35,141 35,141 ±0
Total mapped flash 3,098,919 3,098,481 +438 (+0.0%)
Inside each subsystem

FrameOS core (Nim) — 476,051

Part This PR v2026.10.16 Δ
frameos/js_runtime 115,656 115,612 +44 (+0.0%)
frameos/utils 110,853 110,853 ±0
frameos/interpreter.nim 100,679 100,659 +20 (+0.0%)
embedded_main.nim 19,120 19,120 ±0
embedded_runtime.nim 17,593 17,593 ±0
lib/tz.nim 16,589 16,589 ±0
frameos_nim_glue.c.obj 11,427 11,455 -28 (-0.2%)
frameos/planner.nim 9,574 9,574 ±0
frameos/event_loop.nim 8,143 8,143 ±0
frameos/types.nim 7,715 7,715 ±0
frameos/values.nim 7,528 7,528 ±0
frameos/apps.nim 6,431 6,431 ±0
frameos/single_scene_host.nim 6,379 6,379 ±0
frameos/spool.nim 5,560 5,560 ±0
frameos/input_state.nim 4,676 4,676 ±0
embedded_scene.nim 4,654 4,654 ±0
frameos/events_gen.nim 3,967 3,967 ±0
fos_netguard.c.obj 3,532 3,532 ±0
frameos/app_config.nim 2,734 2,734 ±0
frameos/node_config.nim 2,582 2,582 ±0
frameos/app_capabilities.nim 2,473 2,473 ±0
frameos/events.nim 2,335 2,335 ±0
frameos/reboot_reason.nim 2,332 2,332 ±0
frameos/refresh_interval.nim 1,593 1,593 ±0
frameos/runtime_diagnostics.nim 775 775 ±0
fos_version.c.obj 413 328 +85 (+25.9%)
frameos/event_log.nim 407 407 ±0
frameos/channels.nim 153 153 ±0
frameos/ids.nim 120 120 ±0
frameos/hal 44 44 ±0
frameos/retired_apps.nim 14 14 ±0

QuickJS — 360,285

Part This PR v2026.10.16 Δ
quickjs.c.obj 287,746 287,746 ±0
libunicode.c.obj 50,178 50,178 ±0
libregexp.c.obj 14,007 14,007 ±0
dtoa.c.obj 5,689 5,689 ±0
cutils.c.obj 2,141 2,141 ±0
fos_qjs_glue.c.obj 449 449 ±0
fos_quickjs_tz.c.obj 75 75 ±0

pixie — 296,919

Part This PR v2026.10.16 Δ
pixie/fontformats/opentype.nim 56,062 56,066 -4 (-0.0%)
pixie/fileformats/webp.nim 36,937 36,937 ±0
pixie/fileformats/svg.nim 35,546 35,546 ±0
pixie/paths.nim 31,592 31,616 -24 (-0.1%)
pixie/fileformats/jpeg.nim 29,160 29,164 -4 (-0.0%)
pixie/fileformats/png.nim 21,475 21,475 ±0
pixie/images.nim 15,445 15,445 ±0
pixie/fonts.nim 10,301 10,301 ±0
pixie/paints.nim 9,019 9,023 -4 (-0.0%)
pixie/fileformats/bmp.nim 7,612 7,612 ±0
pixie/common.nim 7,154 7,158 -4 (-0.1%)
pixie/blends.nim 6,622 6,622 ±0
pixie/fileformats/gif.nim 5,737 5,737 ±0
pixie.nim 5,243 5,243 ±0
pixie/inflatestream.nim 5,164 5,156 +8 (+0.2%)
pixie/fileformats/webp_vp8_tables.nim 3,881 3,881 ±0
pixie/fileformats/ppm.nim 3,520 3,520 ±0
pixie/contexts.nim 2,951 2,951 ±0
pixie/fileformats/qoi.nim 2,437 2,437 ±0
pixie/internal.nim 506 502 +4 (+0.8%)
pixie/rgb565.nim 315 327 -12 (-3.7%)
pixie/fontformats/svgfont.nim 190 190 ±0
pixie/decodebudget.nim 50 50 ±0

Wi-Fi stack — 295,296

Part This PR v2026.10.16 Δ
libnet80211.a 136,148 136,148 ±0
libpp.a 62,158 62,158 ±0
libwpa_supplicant.a 54,904 54,904 ±0
libphy.a 34,176 34,176 ±0
libesp_wifi.a 4,788 4,788 ±0
libesp_phy.a 2,541 2,541 ±0
libesp_coex.a 291 291 ±0
libcore.a 287 287 ±0
libespnow.a 3 3 ±0

Nim stdlib — 247,632

Part This PR v2026.10.16 Δ
pure/collections/tables.nim 72,122 72,114 +8 (+0.0%)
system.nim 48,179 48,163 +16 (+0.0%)
pure/unicode.nim 17,324 17,324 ±0
pure/times.nim 16,493 16,493 ±0
pure/json.nim 13,478 13,478 ±0
std/private/dragonbox.nim 10,348 10,348 ±0
pure/strutils.nim 7,847 7,847 ±0
pure/parsexml.nim 5,802 5,802 ±0
pure/algorithm.nim 5,324 5,324 ±0
pure/base64.nim 5,107 5,107 ±0
pure/hashes.nim 4,003 4,003 ±0
std/formatfloat.nim 3,476 3,476 ±0
pure/xmlparser.nim 3,407 3,407 ±0
pure/parsejson.nim 3,392 3,392 ±0
pure/uri.nim 2,988 2,988 ±0
pure/streams.nim 2,749 2,749 ±0
pure/strformat.nim 2,380 2,380 ±0
std/syncio.nim 2,282 2,282 ±0
pure/collections/sets.nim 2,089 2,089 ±0
pure/xmltree.nim 1,862 1,862 ±0
pure/lexbase.nim 1,775 1,775 ±0
pure/parseutils.nim 1,741 1,741 ±0
system/exceptions.nim 1,530 1,530 ±0
pure/strtabs.nim 1,507 1,507 ±0
pure/pathnorm.nim 1,212 1,212 ±0
pure/collections/lists.nim 990 990 ±0
std/private/ospaths2.nim 966 966 ±0
pure/collections/deques.nim 844 844 ±0
pure/math.nim 839 839 ±0
pure/options.nim 815 815 ±0
pure/random.nim 688 688 ±0
std/private/digitsutils.nim 617 617 ±0
std/private/osdirs.nim 510 510 ±0
std/oserrors.nim 489 489 ±0
std/monotimes.nim 485 485 ±0
system/dollars.nim 431 431 ±0
std/private/oscommon.nim 325 325 ±0
std/envvars.nim 306 310 -4 (-1.3%)
std/private/ossymlinks.nim 187 187 ±0
std/private/decode_helpers.nim 181 181 ±0
pure/bitops.nim 162 162 ±0
pure/os.nim 99 99 ±0
std/private/osfiles.nim 96 96 ±0
core/macros.nim 89 89 ±0
std/assertions.nim 87 87 ±0
system/ctypes.nim 9 9 ±0

ESP-IDF misc — 181,413

Part This PR v2026.10.16 Δ
libesp_hw_support.a 37,620 37,620 ±0
libhal.a 21,865 21,865 ±0
libfreertos.a 17,240 17,240 ±0
libesp_system.a 13,736 13,736 ±0
libesp_driver_uart.a 11,627 11,627 ±0
libheap.a 8,660 8,660 ±0
libesp_driver_i2c.a 8,062 8,062 ±0
libesp_driver_spi.a 7,760 7,760 ±0
libconsole.a 5,733 5,733 ±0
libjson.a 4,940 4,940 ±0
libesp_driver_gpio.a 3,878 3,878 ±0
libbootloader_support.a 3,813 3,813 ±0
libxtensa.a 3,691 3,691 ±0
libesp_driver_usb_serial_jtag.a 3,408 3,408 ±0
libesp_ringbuf.a 3,322 3,322 ±0
libesp_event.a 3,241 3,241 ±0
libesp_driver_ledc.a 3,054 3,054 ±0
libapp_update.a 2,484 2,414 +70 (+2.9%)
libesp_mm.a 2,451 2,451 ±0
libesp_timer.a 2,337 2,337 ±0
libsoc.a 2,316 2,316 ±0
libesp_adc.a 2,285 2,285 ±0
libesp_psram.a 2,172 2,172 ±0
libpthread.a 1,397 1,397 ±0
liblog.a 1,375 1,375 ±0
libesp_security.a 1,050 1,050 ±0
libesp_rom.a 902 902 ±0
libesp_app_format.a 507 507 ±0
libxt_hal.a 437 437 ±0
libesp_common.a 26 26 ±0
libesp_pm.a 24 24 ±0

FrameOS apps (Nim) — 181,348

Part This PR v2026.10.16 Δ
apps/data/icalJson 50,262 50,262 ±0
apps/render/calendar 29,944 29,944 ±0
apps/data/localImage 10,340 10,340 ±0
apps/render/split 9,389 9,389 ±0
apps/data/eventsToAgenda 8,568 8,568 ±0
apps/render/zoomPan 8,360 8,360 ±0
apps/apps.nim 7,208 7,208 ±0
apps/render/text 5,234 5,234 ±0
apps/data/xmlToJson 5,190 5,190 ±0
apps/render/svg 4,583 4,583 ±0
apps/render/image 4,423 4,423 ±0
apps/logic/setAsState 3,181 3,181 ±0
apps/data/downloadImage 3,128 3,128 ±0
apps/data/qr 3,017 3,017 ±0
apps/render/gradient 2,983 2,983 ±0
apps/data/rotateImage 2,939 2,939 ±0
apps/data/downloadUrl 2,774 2,774 ±0
apps/data/resizeImage 2,312 2,312 ±0
apps/data/newImage 2,175 2,175 ±0
apps/render/color 2,059 2,059 ±0
apps/render/opacity 2,055 2,055 ±0
apps/data/log 2,053 2,053 ±0
apps/data/prettyJson 1,947 1,947 ±0
apps/data/clock 1,718 1,718 ±0
apps/data/parseJson 1,585 1,585 ±0
apps/logic/nextSleepDuration 1,394 1,394 ±0
apps/logic/ifElse 1,311 1,311 ±0
apps/logic/breakIfRendering 1,216 1,216 ±0

Embedded font — 146,358

Part This PR v2026.10.16 Δ
assets/fonts.nim 146,358 146,358 ±0

fos_ firmware shell (C)* — 136,750

Part This PR v2026.10.16 Δ
fos_http.c.obj 22,252 22,185 +67 (+0.3%)
fos_cloud.c.obj 19,672 19,651 +21 (+0.1%)
fos_console.c.obj 13,061 14,001 -940 (-6.7%)
fos_client.c.obj 12,975 12,957 +18 (+0.1%)
fos_settings.c.obj 7,722 7,722 ±0
fos_scenes.c.obj 7,515 7,515 ±0
fos_ota.c.obj 5,902 5,639 +263 (+4.7%)
fos_cloud_contract.c.obj 4,768 4,768 ±0
fos_config.c.obj 4,619 4,619 ±0
fos_wifi.c.obj 3,295 3,189 +106 (+3.3%)
fos_assets.c.obj 3,124 3,124 ±0
fos_sd_probe.c.obj 2,753 2,753 ±0
fos_buttons.c.obj 2,737 2,737 ±0
fos_schedule.c.obj 2,624 2,614 +10 (+0.4%)
fos_assets_sd.c.obj 2,484 2,484 ±0
fos_events.c.obj 2,332 2,332 ±0
fos_panel_draw.c.obj 2,229 2,229 ±0
main.c.obj 1,703 1,703 ±0
fos_config_parse.c.obj 1,467 1,467 ±0
fos_url_guard.c.obj 1,397 1,397 ±0
fos_tz.c.obj 1,294 1,294 ±0
fos_buzzer.c.obj 1,162 1,162 ±0
fos_battery.c.obj 1,140 1,140 ±0
fos_minisig.c.obj 1,140 1,140 ±0
fos_backend_http.c.obj 1,072 1,072 ±0
fos_commands.c.obj 940 940 ±0
fos_status_screen.c.obj 893 893 ±0
fos_lan_access.c.obj 841 841 ±0
fos_scene_state.c.obj 650 650 ±0
fos_wake.c.obj 598 199 +399 (+200.5%)
fos_assets_path.c.obj 564 259 +305 (+117.8%)
fos_framebuffer.c.obj 483 483 ±0
fos_button_timing.c.obj 434 434 ±0
fos_board.c.obj 334 334 ±0
fos_power.c.obj 241 241 ±0
fos_battery_filter.c.obj 214 214 ±0
fos_json_guard.c.obj 119 119 ±0

String pool (attributed to efuse) — 136,684

Part This PR v2026.10.16 Δ
esp_efuse_utility.c.obj 135,638 135,683 -45 (-0.0%)
esp_efuse_rtc_calib.c.obj 566 566 ±0
esp_efuse_table.c.obj 268 268 ±0
esp_efuse_api.c.obj 151 151 ±0
esp_efuse_startup.c.obj 61 61 ±0

mbedTLS + certificates — 132,427

Part This PR v2026.10.16 Δ
libmbedcrypto.a 71,291 71,291 ±0
libmbedtls.a 45,799 45,799 ±0
libmbedx509.a 7,080 7,080 ±0
libesp-tls.a 6,705 6,705 ±0
libesp_https_server.a 1,552 1,552 ±0

lwIP / HTTP / WebSocket — 126,935

Part This PR v2026.10.16 Δ
liblwip.a 78,525 78,529 -4 (-0.0%)
libhttp_parser.a 10,350 10,350 ±0
libesp_http_server.a 10,020 10,020 ±0
libtcp_transport.a 8,245 8,245 ±0
libespressif__esp_websocket_client.a 6,822 6,822 ±0
libesp_http_client.a 6,666 6,666 ±0
libesp_netif.a 6,307 6,307 ±0

libc / libm / newlib — 116,263

Part This PR v2026.10.16 Δ
libc.a 76,471 76,471 ±0
libm.a 31,563 31,563 ±0
libnewlib.a 6,609 6,609 ±0
libstdc++.a 1,476 1,476 ±0
libgcc.a 98 98 ±0
libcxx.a 46 46 ±0

Storage (SPIFFS / FatFS / SD / NVS) — 94,068

Part This PR v2026.10.16 Δ
libspiffs.a 20,380 20,380 ±0
libfatfs.a 20,141 20,141 ±0
libspi_flash.a 14,168 14,168 ±0
libnvs_flash.a 13,665 13,665 ±0
libsdmmc.a 13,013 13,013 ±0
libvfs.a 6,196 6,196 ±0
libesp_driver_sdspi.a 3,866 3,866 ±0
libesp_partition.a 1,956 1,956 ±0
libesp_vfs_console.a 678 678 ±0
libnvs_sec_provider.a 5 5 ±0

Nim packages (chrono, zippy, chroma, qrgen, ...) — 70,320

Part This PR v2026.10.16 Δ
QRgen 3.1.0 21,886 21,886 ±0
chrono 0.3.1 15,025 15,049 -24 (-0.2%)
zippy 0.10.19 14,936 14,936 ±0
chroma 1.0.0 14,388 14,368 +20 (+0.1%)
checksums 0.2.1 3,290 3,290 ±0
flatty 0.3.4 530 530 ±0
jsony 1.1.5 148 148 ±0
bumpy 1.1.3 117 113 +4 (+3.5%)

Display drivers (C) — 65,029

Part This PR v2026.10.16 Δ
(everything else) 21,278 21,278 ±0
frameos_panel_table.c.obj 6,685 6,685 ±0
EPD_13in3e.c.obj 1,796 1,796 ±0
EPD_3in7.c.obj 1,564 1,564 ±0
EPD_5in79.c.obj 1,481 1,481 ±0
DEV_Debug.c.obj 1,313 1,313 ±0
EPD_2in7.c.obj 1,292 1,292 ±0
EPD_4in2.c.obj 1,262 1,262 ±0
EPD_7in3e.c.obj 1,208 1,208 ±0
EPD_4in2_V2.c.obj 1,184 1,184 ±0
DEV_Config_esp.c.obj 1,180 1,180 ±0
EPD_4in26.c.obj 1,123 1,123 ±0
29 smaller rows 23,663 23,596 +67 (+0.3%)

Crypto (monocypher) — 35,141

Part This PR v2026.10.16 Δ
monocypher.c.obj 31,916 31,916 ±0
monocypher-ed25519.c.obj 3,225 3,225 ±0
Biggest movers (per object)
Object Δ This PR Baseline
fos_console.c.obj -940 13,061 14,001
fos_ota.c.obj +263 5,902 5,639
fos_http.c.obj +67 22,252 22,185
esp_efuse_utility.c.obj -45 135,638 135,683
frameos/js_runtime/app_runtime.nim +28 72,810 72,782
frameos_nim_glue.c.obj -28 11,427 11,455
pkgs/pixie-6.1.0/pixie/paths.nim -24 31,592 31,616
pkgs/chrono-0.3.1/chrono.nim -24 15,025 15,049
fos_cloud.c.obj +21 19,672 19,651
frameos/interpreter.nim +20 100,679 100,659
fos_client.c.obj +18 12,975 12,957
pkgs/chroma-1.0.0/chroma.nim +16 4,834 4,818
nim/lib/system.nim +16 48,179 48,163
pkgs/pixie-6.1.0/pixie/inflatestream.nim +8 5,164 5,156
nim/lib/pure/collections/tables.nim +8 72,122 72,114
Largest 30 objects
Object Subsystem This PR v2026.10.16 Δ
quickjs.c.obj QuickJS 287,746 287,746 ±0
assets/fonts.nim Embedded font 146,358 146,358 ±0
esp_efuse_utility.c.obj String pool (attributed to efuse) 135,638 135,683 -45 (-0.0%)
frameos/interpreter.nim FrameOS core (Nim) 100,679 100,659 +20 (+0.0%)
frameos/js_runtime/app_runtime.nim FrameOS core (Nim) 72,810 72,782 +28 (+0.0%)
nim/lib/pure/collections/tables.nim Nim stdlib 72,122 72,114 +8 (+0.0%)
pkgs/pixie-6.1.0/pixie/fontformats/opentype.nim pixie 56,062 56,066 -4 (-0.0%)
libunicode.c.obj QuickJS 50,178 50,178 ±0
nim/lib/system.nim Nim stdlib 48,179 48,163 +16 (+0.0%)
apps/data/icalJson/ical.nim FrameOS apps (Nim) 44,746 44,746 ±0
pkgs/pixie-6.1.0/pixie/fileformats/webp.nim pixie 36,937 36,937 ±0
pkgs/pixie-6.1.0/pixie/fileformats/svg.nim pixie 35,546 35,546 ±0
frameos/utils/image.nim FrameOS core (Nim) 35,259 35,259 ±0
monocypher.c.obj Crypto (monocypher) 31,916 31,916 ±0
pkgs/pixie-6.1.0/pixie/paths.nim pixie 31,592 31,616 -24 (-0.1%)
frameos/js_runtime/runtime.nim FrameOS core (Nim) 31,338 31,330 +8 (+0.0%)
pkgs/pixie-6.1.0/pixie/fileformats/jpeg.nim pixie 29,160 29,164 -4 (-0.0%)
apps/render/calendar/app.nim FrameOS apps (Nim) 22,841 22,841 ±0
fos_http.c.obj fos_* firmware shell (C) 22,252 22,185 +67 (+0.3%)
pkgs/pixie-6.1.0/pixie/fileformats/png.nim pixie 21,475 21,475 ±0
fos_cloud.c.obj fos_* firmware shell (C) 19,672 19,651 +21 (+0.1%)
embedded_main.nim FrameOS core (Nim) 19,120 19,120 ±0
x509_crt_bundle.S.obj mbedTLS + certificates 17,928 17,928 ±0
embedded_runtime.nim FrameOS core (Nim) 17,593 17,593 ±0
nim/lib/pure/unicode.nim Nim stdlib 17,324 17,324 ±0
frameos/utils/asset_colors.nim FrameOS core (Nim) 17,028 17,028 ±0
lib/tz.nim FrameOS core (Nim) 16,589 16,589 ±0
frameos/utils/status_screen.nim FrameOS core (Nim) 16,551 16,551 ±0
nim/lib/pure/times.nim Nim stdlib 16,493 16,493 ±0
ieee80211_ioctl.o Wi-Fi stack 15,592 15,592 ±0

Flash = .text + .rodata from the linker map via esp_idf_size; "Inside each subsystem" splits every bucket one level down (the Nim core by directory, apps by app, packages by package, ESP-IDF by archive) over all objects, not just the largest. "String pool (attributed to efuse)" is the linker's merged string-literal pool for the whole image, not efuse code — see docs/esp32-image-size.md.

@mariusandra
mariusandra merged commit 523bf3d into main Oct 18, 2026
23 checks passed
@mariusandra
mariusandra deleted the lows-esp32 branch October 18, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant