diff --git a/tools/features.toml b/tools/features.toml index 7b5674cf..7f2a1a56 100644 --- a/tools/features.toml +++ b/tools/features.toml @@ -466,17 +466,24 @@ ota_trust_bench = true # DOIS numeros e o teto de OTA e o mais apertado: so ALARMS_PAGE fora deixou o .bin # 1.420 B acima do teto de 1.040.384 B mesmo com a regiao cabendo. Sao as duas paginas # que um soak HTTPS menos toca; TEL_PAGE entra por folga (com duas fora o .bin ficava -# 3.732 B sob o teto, menos de um setor de 4 KiB). Suba data/web/{alarms,files,tel}. +# 3.732 B sob o teto, menos de um setor de 4 KiB). Suba data/web/{alarms,files,tel,license}. # html.gz para /web/ antes de uma suite, ou as rotas dao "Page asset missing" (POST # /api/upload, nunca uploadfs). Isenta do teto de OTA desde 2026-10-02 (ota_exempt em # tools/flash_budget.json, B6 do PLANO_STABLE.md). O limite que sobra e o fim do slot do # programa, onde o linker recusa a imagem: no #233 o .bin (1.039.996 B) estava a 4.484 B # dele, menos que a menor das tres paginas (alarms, 4.490 B gz). Trazer uma de volta pede -# medir de novo. +# medir de novo. LICENSE_PAGE (2026-10-22, a opcao (a) do mantenedor para o S10b-2 do +# feat/ui-drivers): a regiao FLASH tinha 44 B de folga (o ultimo LOAD terminava em +# 0x100FEFD4 contra 0x100FF000, readelf -l) e o S10b-2 cresce esta imagem ~160 B. Das +# paginas que a regra do build_webui_gz.py deixa sair (grande, pouco aberta, dispensavel +# para subir o aparelho), medidas neste env no mesmo dia em gz: DASH 6.237 B e a mais +# aberta; NET 4.304 B pode ser a que poe um aparelho novo no Wi-Fi; LICENSE 4.260 B; USR +# 3.140 B. Suba tambem data/web/license.html.gz: o web_test_suite.py abre /license e +# acusa "Page asset missing" sem ele. [profiles.pico_w_test_https] extends = "pico_w_test" web_https = true -custom_fs_pages = ["ALARMS_PAGE", "FILE_PAGE", "TEL_PAGE"] +custom_fs_pages = ["ALARMS_PAGE", "FILE_PAGE", "TEL_PAGE", "LICENSE_PAGE"] # pico_w_asserts — release com o invariante 3 de concorrencia armado (T1.6). Nao publicada. # -DSIMUT_CONCURRENCY_ASSERTS transforma FLASH_OP num tripwire que loga quem entra nele diff --git a/tools/flash_budget.json b/tools/flash_budget.json index 3c5574f7..ababc070 100644 --- a/tools/flash_budget.json +++ b/tools/flash_budget.json @@ -535,8 +535,8 @@ "(ota_exempt, with the reason) and records no 'bin'; its budget still holds." ], "ceiling": 1044480, - "measured_on": "2026-10-05 chore/v2.11.1: SIMUT_VERSION 2.11.1, the only source change. All seven rebuilt here. The version has as many characters as 2.11.0, but the login page carries it, and its gzip came out 5 B smaller in every image: measured and .bin 8 B under the record on release, test, asserts and pico2_w_release; alpha, air and test_https equal, their alignment absorbing it. Budgets unchanged. 2026-10-12 feat/lan-switch: pico_wire joins (the SIMUT Wire, a plain Pico with the network on an ENC28J60, no driver yet), measured 587,980 B and a .bin of 600,016 B; the seven others are byte for byte what main 2a391da builds. Then twelve sensor slots (-DMAX_SENSORS=12, GP12-GP15 are the module's): 588,020 B and a .bin of 600,056 B, +40 B for clearing the slots past the twelfth on every config load; RAM 102,416 -> 102,064 B. Then eleven (the module's INT moved to GP11, 2026-10-12): 587,972 B and a .bin of 600,008 B, RAM 101,980 B, measured on 28a54c8. 2026-10-13 feat/wire-driver: the wired driver takes pico_wire to 597,448 B and a .bin of 609,480 B (RAM 104,680 B); the seven Wi-Fi images stay byte for byte what dd7efdc builds until the top-panel fix, which grows them by 32 to 64 B (release, test, test_https and asserts +48, alpha +64, air +32, pico2_w_release +56; .bin +48 on release, test and asserts, +56 on pico2_w_release, unchanged on alpha and air). All eight measured at 4912762's tree plus this change. The review's fixes (module before the sensors, the static address checks, the MAC before the start, syslog and the OTA teardown on the cable, the log latches): pico_wire 598,560 B (+1,112 B), .bin 610,592 B, RAM 104,688 B; the seven Wi-Fi images compile none of it. 2026-10-13 feat/wire-surface: pico_wiretft joins (the SIMUT Wire with the TFT panel and touch): 780,628 B and a .bin of 792,664 B (RAM 109,784 B), built on the driver's tree plus the manifest entry and no change to src/. The eight others keep their records: no flag and no source of theirs moved. Then the surface a wired build loses with the radio (the web pages, the console, the panels and the third-party list): pico_wire 595,632 B and a .bin of 607,664 B (RAM 104,684 B), pico_wiretft 777,428 B and a .bin of 789,464 B (RAM 109,788 B), both budgets brought down to them; the seven radio images byte for byte the same at each of the branch's commits, compared by sha256 (pico_w_release 8b565f66 throughout). Then the captive-portal redirect and probes, the setup AP's, compiled out of the wired builds: pico_wire 595,016 B (.bin 607,048), pico_wiretft 776,820 B (.bin 788,856), RAM unchanged; budgets brought down again. Then four log codes of the cable's own (529-532) with their three rows in the edge filter, compiled into the wired builds only: pico_wire 595,152 B (+136, .bin 607,184), pico_wiretft 776,956 B (+136, .bin 788,992); the seven radio images unchanged. 2026-10-13 feat/net-boundary: the wired link generic over LwipIntfDev (the chip in a device header, src/net/Enc28j60Device.h) and a module stopped by an update that did not happen started again by the retry: pico_wire 595,208 B (+56, .bin 607,240), pico_wiretft 777,004 B (+48, .bin 789,040), RAM unchanged. The move alone is byte for byte neutral (pico_wire sha256 3edd1440, pico_wiretft e58d65e9, before WiredLink::chipName( ) existed); the growth is the module-fail message built from the driver's name (a second concatenation in startWired( ), plus chipName( ) and started( ) now reached) and the restart path in wiredLost( ), the only two function bodies that differ in the normalized disassembly of both images; the seven radio images are byte for byte the same. Then the log line of that path names what happened (\"module stopped\", where it said \"link down\"): +48 B on both, pico_wire 595,256 B (.bin 607,288), pico_wiretft 777,052 B (.bin 789,088); the seven radio images unchanged. Then the review of that change: the stopped module is looked for first in updateWired( ), in every state, because a unit still on its way up (NET_CONNECTING: booted with the cable out, or a lease pending) never reached wiredLost( ) and was never started again: +40 B on both, pico_wire 595,296 B (.bin 607,328), pico_wiretft 777,092 B (.bin 789,128), RAM unchanged; updateWired( ) and wiredLost( ) the only two function bodies that differ in the normalized disassembly of both images. The seven radio images are byte for byte the same, pico_w_air included: its radio power-down moved into net::powerDownForSleep( ) (src/net/NetLink.h) without moving a byte. 2026-10-13 feat/net-radio-unit: the radio's state machine moved from NetworkManager.cpp into its own unit, src/net/NetworkManager_Cyw43.cpp, which the wired images do not build, and NetworkManager.cpp became the host of what every network needs, reaching the link through three methods each unit defines. The wired images lose the radio code they compiled dead: pico_wire 590,740 B (-4,556, .bin 602,776), pico_wiretft 772,852 B (-4,240, .bin 784,888), both budgets brought down. The radio images pay for the split: release +48 B (1,021,180, .bin 1,033,212), asserts +40 (1,023,468, .bin 1,035,500), pico2_w_release +120 (997,328, .bin 997,352), test_https -8 (1,030,692), test, alpha and air the same; the normalized disassembly of all seven differs in four bodies only: begin( ) and update( ) (now the host's), handleConnecting( ) and getRssi( ), which call resetReconnectLadder( ) and isConnected( ) across the unit boundary where the compiler inlined them before. Inlining the two helpers in the header instead was measured and grew the radio images more (release +88, test +56, asserts +80). 2026-10-13 fix/radio-link-in-ntp-wait: the radio watches its link inside the NTP wait, one check in its updateLinkFirst( ) and NET_READY's loss in a helper that logs it, wifiLost( ). The seven radio images grow: release +72 B (1,021,252, .bin 1,033,284), test +80 (1,025,788, .bin 1,037,820, under its budget), test_https +80 (1,030,772), asserts +80 (1,023,548, .bin 1,035,580), alpha +88 (975,060, under its budget, the .bin the same), air +80 (1,018,336, under its budget, the .bin the same), pico2_w_release +72 (997,400, .bin 997,424); the two wired images are byte for byte the same. With the log at each of the two callers instead of in the helper, release grew +96 B. 2026-10-13 fix/silent-radio-no-blind-join (#266): a reconnect scan whose start the radio did not answer, and that never finished, is not escaped by a blind join; two in a row past the first half hour restart the radio by safeReboot( ). The radio images grow: release +376 B (1,021,628, .bin 1,033,660), test +352 (1,026,140, .bin 1,038,172), test_https +352 (1,031,124), asserts +384 (1,023,932, .bin 1,035,964), alpha +280 (975,340) and air +280 (1,018,616), both .bin the same, pico2_w_release +376 (997,776, .bin 997,800). The wired images carry the two new members of the shared header and the host's reset of one: pico_wire the same size (590,740), pico_wiretft +16 (772,868, .bin 784,904). Writing the two log lines with one snprintf each instead of the String concatenations was measured: 16 B less on release, not worth the buffer. 2026-10-14 fix/link-health-in-ntp-wait: getRssi( ) answers the level of any link that is up, the NTP wait included, on the radio and on the cable (isLinkUp( ) where it read isConnected( )). The RP2040 images are the same size; pico2_w_release +8 B (997,784, .bin 997,808). With it, the Air's FLUSH waits for NTP 10 s at most (AIR_FLUSH_NTP_WAIT_MS, airFlushNetLost( )): pico_w_air +48 B (1,018,664, the .bin the same), the other eight byte for byte the same. 2026-10-14 fix/web-short-write: override 2m (webserver_short_write.patch), a write cut short ends the response and closes the client as its real type (stopClient( ), so over TLS too), and the count read out (metr.cgw, /metrics, and `show net status` with the TCP segment pool and tcp_write's memory failures). Every image grows: release +512 B (1,022,140, .bin 1,034,172), test +480 (1,026,620, .bin 1,038,652), test_https +504 (1,031,628), asserts +504 (1,024,436, .bin 1,036,468), alpha +344 (975,684) and air +352 (1,019,016), both .bin the same, pico2_w_release +520 (998,304, .bin 998,328), pico_wire +480 (591,220, .bin 603,256), pico_wiretft +504 (773,372, .bin 785,408). Of the release's 512 B, 394 are sized symbols (the status handler 72, _writeAll( ) and _shortWrite( ) 78, the console 56, the metrics 32, the three _currentClientStop( ) 32, the framework's call sites and WebManager the rest) and the rest the new strings. 2026-10-14 fix/web-fewer-writes: override 2n (webserver_fewer_writes.patch), HTTPServer collects a response's small writes in a buffer of one TCP segment and sends them together (#189). Every image grows: release +328 B (1,022,468, .bin 1,034,500), test +328 (1,026,948, .bin 1,038,980, 1,163 B of OTA headroom left), test_https +328 (1,031,956), asserts +328 (1,024,764, .bin 1,036,796), alpha +328 (976,012, the .bin the same), air +328 (1,019,344) with its .bin +4,096 (1,035,340), pico2_w_release +296 (998,600, .bin 998,624), pico_wire +328 (591,548, .bin 603,584), pico_wiretft +328 (773,700, .bin 785,736). The Air's .bin moves in 4 KB steps, as the alpha's does: their .rodata starts on a 4 KB boundary because it holds BTstack's __bluetooth_tlv (8 KB, sector-aligned), and the Air's .text ended 196 B short of the next step. Against main's release the sized symbols grow 362 B and the image 328: _outAppend( ) 140, the constructor's malloc( ) 56, _outBodySent( ) 32, _outFlush( ) 22, and the flushes and resets in send( ), sendContent( ), _prepareHeader( ), _handleRequest( ), _finalizeResponse( ) and the destructor the rest. The 1,460 B buffer is heap, allocated with the server. As an array among the class's members instead of behind a pointer at its end, it pushed every member after it past the Cortex-M0+'s short load/store offsets: release +1,152 B, against +352 B for the same code behind the pointer. The bench ran the release of the branch's first version (sha256 b1a7e7da), which had two more stores, _outLen = 0 in _shortWrite( ), which nothing reaches, and in stopClient( ), which runs but changes nothing: what it would drop goes to a client already closed, whose writes return 0. The final normalized disassembly differs from the bench image's in _shortWrite( ) and dropAbortedStream( ) only, 16 B. 2026-10-15 deps/pico-enc28j60-1.3.1: the ENC28J60 library moves from fb16ec1 to the commit of v1.3.1 (4984e2f), whose lwIP interface keeps up to eight frames in the chip and uploads one while the one before is on the wire (the library's 1.3.0; 1.3.1 changed an example and the documentation only). The wired images grow: pico_wire +568 B (592,116, .bin 604,152), pico_wiretft +624 (774,324, .bin 786,360), RAM +56 on both (the queue's state in the driver object). Nearly all of it is the new send path (_sendQueued( ) 228, _sendPoll( ), _sendFinish( ) and enc28j60_frame_send_finish_blk( ) 100 each, _sendStartNext( ) 80, against sendFrame( ) -144 and enc28j60_frame_send_blk( ) -90); the /license page, whose third-party note names the new commit, 12. The seven radio images are byte for byte main's (192e1ad), compared by sha256. 2026-10-15 fix/wire-tft-flash-render-274: the WiFiServerSecure accept override (wifiserversecure_drop_plaintext.patch, patch.sh 2b-ter) drops a non-TLS client on the TLS port before the BearSSL handshake, decided from its first byte (#274). It is compiled wherever SIMUT_WEB_HTTPS is set, so the five HTTPS images grow: pico_wiretft +56 B (774,380, .bin 786,416), release +48 (1,022,516, .bin 1,034,548), test_https +48 (1,032,004), asserts +56 (1,024,820, .bin 1,036,852), pico2_w_release +24 (998,624, .bin 998,648). pico_wire, pico_w_test, alpha and air compile no HTTPS server, so the patched accept path is not in them and they keep main's sizes (d5f7063). 2026-10-15 perf/tft-spi-clk-peri: setup( ) clocks clk_peri from clk_sys on the six images that drive the panel and SIMUT_TFT_SPI_HZ is 66.5 MHz; /api/status gains sys.clk_peri and sys.tft_hz through macros, so the images without the panel compile the very tokens they did. Flash used (.bin): release +216 (1,022,732, .bin 1,034,764), test +208 (1,027,156, .bin 1,039,188), test_https +208 (1,032,212), asserts +208 (1,025,028, .bin 1,037,060), pico2_w_release +224 (998,848, .bin 998,872), wiretft +208 (774,588, .bin 786,624). pico_wire, alpha and air are byte for byte main's (80c3c88), compared by sha256. 2026-10-16 fix/injected-touch-never-ends: the injected touch (POST /api/touch, `touch sim`, `touch hold`) ends in loopCore1( ) right after handleTouch( ) instead of inside mapTouchPoint( ); the sensitivity screen's Cancelar takes an injection and records its provenance (_lastTouchInjected) before the accept, and the calibration's measuring phase ignores it, with simNow read once per handleTouch( ). Flash used (.bin): release +40 (1,022,772, .bin 1,034,804), test +40 (1,027,196, .bin 1,039,228), test_https +40 (1,032,252), asserts +40 (1,025,068, .bin 1,037,100), pico2_w_release +24 (998,872, .bin 998,896), wiretft +48 (774,636, .bin 786,672). The provenance store is 16 B of that on release, test, test_https, asserts and wiretft and 8 B on pico2_w_release. The same test placed before _rawTouchState, the change's first version, was 8 B smaller on release and test_https and the same on the other four; it released a tap unseen when the first Core 1 pass came later than its hold, so it was dropped. pico_wire, alpha and air come out the size of their records, flash used and .bin; they were not compared by sha256. 2026-10-18 fix/safe-reboot-writes-pending-log: safeReboot( ) writes the log records it holds in RAM (flushPendingIfAny( ) inside the pre-reboot hook's guard, in safeReboot( ) and in the RP2350's safeRebootFlashUpdate( )). Four images grow 8 B, the call: pico_w_test (1,027,204, .bin 1,039,236), pico_w_asserts (1,025,076, .bin 1,037,108), pico2_w_release (998,880, .bin 998,904) and pico_wire (592,124, .bin 604,160). pico_w_release, pico_w_test_https, pico_w_alpha, pico_w_air and pico_wiretft come out the size of their records, flash used and .bin, their alignment absorbing it; RAM unchanged. 2026-10-21 fix/radio-answers-by-return-code (#266, #282): a reconnect scan that started quickly and never finished asks the chip one read (radioRead( ), an antenna-setting ioctl) and goes by the driver's return code, a quick start no longer ends a silent streak, and the minute's RSSI sample and getRssi( ) read cyw43_wifi_get_rssi( )'s return code (readRssi( )) instead of the variable WiFi.RSSI( ) leaves unwritten. On main 7e3f29a6 (#281 in), the seven radio images grow: release +160 B (1,022,932, .bin 1,034,964), test +176 (1,027,380, .bin 1,039,412, 731 B of OTA headroom left), test_https +176 (1,032,428), asserts +160 (1,025,236, .bin 1,037,268), alpha +168 (976,180) and air +168 (1,019,512), both .bin the same, pico2_w_release +184 (999,064, .bin 999,088). The two wired images build no radio unit and are byte for byte main's (pico_wire sha256 f464769b, pico_wiretft e781ea41); RAM unchanged on all nine. 2026-10-21 fix/language-pack-log-records (#283): the language pack's records get their own tag (TAG_I18N, 13) and codes (620-623), the console text of the four carries only its detail, and the tags passed to the LOG_ macros are checked at compile time. On main 2f4bc3d3, the seven images that build the pack loader shrink: release -24 B (1,022,908, .bin 1,034,940), test -32 (1,027,348, .bin 1,039,380, 763 B of OTA headroom left), test_https -24 (1,032,404), asserts -24 (1,025,212, .bin 1,037,244), air -32 (1,019,480, the .bin the same), pico2_w_release -48 (999,016, .bin 999,040), wiretft -24 (774,612, .bin 786,648); their budgets come down. On release: findAndLoadLangFile( ) -92 (its two String concatenations), translateCodeEn( ) +52 (the four new cases), tagStringToId( ) and loadLangFile( ) +4 each, .rodata +8 (the four names against the shorter console texts); the name table moved from tagIdToString( )'s function-local static to LOG_TAG_NAMES, 64 B either way. The two images that do not build the loader grow, raising their budgets: pico_wire +184 (592,308, .bin 604,344: translateCodeEn( ) +52 and tagStringToId( ) +4 in .text, the four names +128 in .rodata) and alpha +56 (976,236, the .bin the same: .text +56, its .rodata absorbing the names in the padding before BTstack's sector-aligned TLV). RAM unchanged on all nine. The check itself costs nothing: the same tree with no static_assert, tagStringToId( ) inline and the old function-local table builds byte-identical images (release sha256 e971dfe8, air e5935de2, wiretft a01a20b2). 2026-10-22 fix/alpha-console-event-names: the alpha's two log lookups, logcodeLookup( ) and trlLookup( ) in DisplayManager_Alpha.cpp, answer nullptr where they answered \"\", which LogManager took as the translation. Each became `movs r0, #0; bx lr`, 4 B, where it loaded a literal, 8 B: pico_w_alpha -8 B (976,228, the .bin the same) and pico_wire -8 B (592,300, .bin 604,336), the two images that build that file. The seven others are byte for byte main's (25e169d), compared by sha256. RAM unchanged on all nine.", - "measured_at_commit": "2026-10-13 feat/wire-driver 4912762 (the seven radio images; the budgets only move here), feat/wire-surface, the log-code commit, and feat/net-boundary, B2 on 20c06b0 plus this change, then ebcf29e plus the review's fixes (pico_wire, pico_wiretft); feat/net-radio-unit on 3055b31 plus this change (all nine); fix/radio-link-in-ntp-wait on 53b6d7b plus this change (the seven radio images).; fix/silent-radio-no-blind-join on 2290638 plus this change (all nine).; fix/link-health-in-ntp-wait on 5293bae plus this change (all nine). measured is the zopfli image PlatformIO prints.; fix/web-short-write on f1b8b8f plus this change (all nine), built against a PlatformIO core that carries the override (PLATFORMIO_CORE_DIR, a hardlinked copy of ~/.platformio patched by patch.sh).; fix/web-fewer-writes on 686a1de plus this change (all nine), built against a PlatformIO core that carries overrides 2m and 2n (PLATFORMIO_CORE_DIR, a hardlinked copy of ~/.platformio patched by patch.sh).; deps/pico-enc28j60-1.3.1 on 192e1ad plus this change (all nine), built against ~/.platformio, which carries overrides 2m and 2n since 2026-10-15.; fix/wire-tft-flash-render-274 on d5f7063 plus this change (the five HTTPS images), built against ~/.platformio patched by patch.sh, which carries overrides 2m, 2n and the WiFiServerSecure accept patch (2b-ter).; perf/tft-spi-clk-peri on 80c3c88 plus this change (the six panel images), built against the ~/.platformio as main left it (its pico_w_release .bin matched the record to the byte before the change).; fix/injected-touch-never-ends on ea4fcb1 plus this change (all nine), built against the ~/.platformio as main left it (its pico_wiretft .bin matched the record to the byte before the change: 786,624 B, sha256 3aff19e8).; fix/safe-reboot-writes-pending-log on 90e82d1 plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.; fix/radio-answers-by-return-code rebased on 7e3f29a6 plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.; fix/language-pack-log-records on 2f4bc3d3 plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.; fix/alpha-console-event-names on 25e169df plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.", + "measured_on": "2026-10-05 chore/v2.11.1: SIMUT_VERSION 2.11.1, the only source change. All seven rebuilt here. The version has as many characters as 2.11.0, but the login page carries it, and its gzip came out 5 B smaller in every image: measured and .bin 8 B under the record on release, test, asserts and pico2_w_release; alpha, air and test_https equal, their alignment absorbing it. Budgets unchanged. 2026-10-12 feat/lan-switch: pico_wire joins (the SIMUT Wire, a plain Pico with the network on an ENC28J60, no driver yet), measured 587,980 B and a .bin of 600,016 B; the seven others are byte for byte what main 2a391da builds. Then twelve sensor slots (-DMAX_SENSORS=12, GP12-GP15 are the module's): 588,020 B and a .bin of 600,056 B, +40 B for clearing the slots past the twelfth on every config load; RAM 102,416 -> 102,064 B. Then eleven (the module's INT moved to GP11, 2026-10-12): 587,972 B and a .bin of 600,008 B, RAM 101,980 B, measured on 28a54c8. 2026-10-13 feat/wire-driver: the wired driver takes pico_wire to 597,448 B and a .bin of 609,480 B (RAM 104,680 B); the seven Wi-Fi images stay byte for byte what dd7efdc builds until the top-panel fix, which grows them by 32 to 64 B (release, test, test_https and asserts +48, alpha +64, air +32, pico2_w_release +56; .bin +48 on release, test and asserts, +56 on pico2_w_release, unchanged on alpha and air). All eight measured at 4912762's tree plus this change. The review's fixes (module before the sensors, the static address checks, the MAC before the start, syslog and the OTA teardown on the cable, the log latches): pico_wire 598,560 B (+1,112 B), .bin 610,592 B, RAM 104,688 B; the seven Wi-Fi images compile none of it. 2026-10-13 feat/wire-surface: pico_wiretft joins (the SIMUT Wire with the TFT panel and touch): 780,628 B and a .bin of 792,664 B (RAM 109,784 B), built on the driver's tree plus the manifest entry and no change to src/. The eight others keep their records: no flag and no source of theirs moved. Then the surface a wired build loses with the radio (the web pages, the console, the panels and the third-party list): pico_wire 595,632 B and a .bin of 607,664 B (RAM 104,684 B), pico_wiretft 777,428 B and a .bin of 789,464 B (RAM 109,788 B), both budgets brought down to them; the seven radio images byte for byte the same at each of the branch's commits, compared by sha256 (pico_w_release 8b565f66 throughout). Then the captive-portal redirect and probes, the setup AP's, compiled out of the wired builds: pico_wire 595,016 B (.bin 607,048), pico_wiretft 776,820 B (.bin 788,856), RAM unchanged; budgets brought down again. Then four log codes of the cable's own (529-532) with their three rows in the edge filter, compiled into the wired builds only: pico_wire 595,152 B (+136, .bin 607,184), pico_wiretft 776,956 B (+136, .bin 788,992); the seven radio images unchanged. 2026-10-13 feat/net-boundary: the wired link generic over LwipIntfDev (the chip in a device header, src/net/Enc28j60Device.h) and a module stopped by an update that did not happen started again by the retry: pico_wire 595,208 B (+56, .bin 607,240), pico_wiretft 777,004 B (+48, .bin 789,040), RAM unchanged. The move alone is byte for byte neutral (pico_wire sha256 3edd1440, pico_wiretft e58d65e9, before WiredLink::chipName( ) existed); the growth is the module-fail message built from the driver's name (a second concatenation in startWired( ), plus chipName( ) and started( ) now reached) and the restart path in wiredLost( ), the only two function bodies that differ in the normalized disassembly of both images; the seven radio images are byte for byte the same. Then the log line of that path names what happened (\"module stopped\", where it said \"link down\"): +48 B on both, pico_wire 595,256 B (.bin 607,288), pico_wiretft 777,052 B (.bin 789,088); the seven radio images unchanged. Then the review of that change: the stopped module is looked for first in updateWired( ), in every state, because a unit still on its way up (NET_CONNECTING: booted with the cable out, or a lease pending) never reached wiredLost( ) and was never started again: +40 B on both, pico_wire 595,296 B (.bin 607,328), pico_wiretft 777,092 B (.bin 789,128), RAM unchanged; updateWired( ) and wiredLost( ) the only two function bodies that differ in the normalized disassembly of both images. The seven radio images are byte for byte the same, pico_w_air included: its radio power-down moved into net::powerDownForSleep( ) (src/net/NetLink.h) without moving a byte. 2026-10-13 feat/net-radio-unit: the radio's state machine moved from NetworkManager.cpp into its own unit, src/net/NetworkManager_Cyw43.cpp, which the wired images do not build, and NetworkManager.cpp became the host of what every network needs, reaching the link through three methods each unit defines. The wired images lose the radio code they compiled dead: pico_wire 590,740 B (-4,556, .bin 602,776), pico_wiretft 772,852 B (-4,240, .bin 784,888), both budgets brought down. The radio images pay for the split: release +48 B (1,021,180, .bin 1,033,212), asserts +40 (1,023,468, .bin 1,035,500), pico2_w_release +120 (997,328, .bin 997,352), test_https -8 (1,030,692), test, alpha and air the same; the normalized disassembly of all seven differs in four bodies only: begin( ) and update( ) (now the host's), handleConnecting( ) and getRssi( ), which call resetReconnectLadder( ) and isConnected( ) across the unit boundary where the compiler inlined them before. Inlining the two helpers in the header instead was measured and grew the radio images more (release +88, test +56, asserts +80). 2026-10-13 fix/radio-link-in-ntp-wait: the radio watches its link inside the NTP wait, one check in its updateLinkFirst( ) and NET_READY's loss in a helper that logs it, wifiLost( ). The seven radio images grow: release +72 B (1,021,252, .bin 1,033,284), test +80 (1,025,788, .bin 1,037,820, under its budget), test_https +80 (1,030,772), asserts +80 (1,023,548, .bin 1,035,580), alpha +88 (975,060, under its budget, the .bin the same), air +80 (1,018,336, under its budget, the .bin the same), pico2_w_release +72 (997,400, .bin 997,424); the two wired images are byte for byte the same. With the log at each of the two callers instead of in the helper, release grew +96 B. 2026-10-13 fix/silent-radio-no-blind-join (#266): a reconnect scan whose start the radio did not answer, and that never finished, is not escaped by a blind join; two in a row past the first half hour restart the radio by safeReboot( ). The radio images grow: release +376 B (1,021,628, .bin 1,033,660), test +352 (1,026,140, .bin 1,038,172), test_https +352 (1,031,124), asserts +384 (1,023,932, .bin 1,035,964), alpha +280 (975,340) and air +280 (1,018,616), both .bin the same, pico2_w_release +376 (997,776, .bin 997,800). The wired images carry the two new members of the shared header and the host's reset of one: pico_wire the same size (590,740), pico_wiretft +16 (772,868, .bin 784,904). Writing the two log lines with one snprintf each instead of the String concatenations was measured: 16 B less on release, not worth the buffer. 2026-10-14 fix/link-health-in-ntp-wait: getRssi( ) answers the level of any link that is up, the NTP wait included, on the radio and on the cable (isLinkUp( ) where it read isConnected( )). The RP2040 images are the same size; pico2_w_release +8 B (997,784, .bin 997,808). With it, the Air's FLUSH waits for NTP 10 s at most (AIR_FLUSH_NTP_WAIT_MS, airFlushNetLost( )): pico_w_air +48 B (1,018,664, the .bin the same), the other eight byte for byte the same. 2026-10-14 fix/web-short-write: override 2m (webserver_short_write.patch), a write cut short ends the response and closes the client as its real type (stopClient( ), so over TLS too), and the count read out (metr.cgw, /metrics, and `show net status` with the TCP segment pool and tcp_write's memory failures). Every image grows: release +512 B (1,022,140, .bin 1,034,172), test +480 (1,026,620, .bin 1,038,652), test_https +504 (1,031,628), asserts +504 (1,024,436, .bin 1,036,468), alpha +344 (975,684) and air +352 (1,019,016), both .bin the same, pico2_w_release +520 (998,304, .bin 998,328), pico_wire +480 (591,220, .bin 603,256), pico_wiretft +504 (773,372, .bin 785,408). Of the release's 512 B, 394 are sized symbols (the status handler 72, _writeAll( ) and _shortWrite( ) 78, the console 56, the metrics 32, the three _currentClientStop( ) 32, the framework's call sites and WebManager the rest) and the rest the new strings. 2026-10-14 fix/web-fewer-writes: override 2n (webserver_fewer_writes.patch), HTTPServer collects a response's small writes in a buffer of one TCP segment and sends them together (#189). Every image grows: release +328 B (1,022,468, .bin 1,034,500), test +328 (1,026,948, .bin 1,038,980, 1,163 B of OTA headroom left), test_https +328 (1,031,956), asserts +328 (1,024,764, .bin 1,036,796), alpha +328 (976,012, the .bin the same), air +328 (1,019,344) with its .bin +4,096 (1,035,340), pico2_w_release +296 (998,600, .bin 998,624), pico_wire +328 (591,548, .bin 603,584), pico_wiretft +328 (773,700, .bin 785,736). The Air's .bin moves in 4 KB steps, as the alpha's does: their .rodata starts on a 4 KB boundary because it holds BTstack's __bluetooth_tlv (8 KB, sector-aligned), and the Air's .text ended 196 B short of the next step. Against main's release the sized symbols grow 362 B and the image 328: _outAppend( ) 140, the constructor's malloc( ) 56, _outBodySent( ) 32, _outFlush( ) 22, and the flushes and resets in send( ), sendContent( ), _prepareHeader( ), _handleRequest( ), _finalizeResponse( ) and the destructor the rest. The 1,460 B buffer is heap, allocated with the server. As an array among the class's members instead of behind a pointer at its end, it pushed every member after it past the Cortex-M0+'s short load/store offsets: release +1,152 B, against +352 B for the same code behind the pointer. The bench ran the release of the branch's first version (sha256 b1a7e7da), which had two more stores, _outLen = 0 in _shortWrite( ), which nothing reaches, and in stopClient( ), which runs but changes nothing: what it would drop goes to a client already closed, whose writes return 0. The final normalized disassembly differs from the bench image's in _shortWrite( ) and dropAbortedStream( ) only, 16 B. 2026-10-15 deps/pico-enc28j60-1.3.1: the ENC28J60 library moves from fb16ec1 to the commit of v1.3.1 (4984e2f), whose lwIP interface keeps up to eight frames in the chip and uploads one while the one before is on the wire (the library's 1.3.0; 1.3.1 changed an example and the documentation only). The wired images grow: pico_wire +568 B (592,116, .bin 604,152), pico_wiretft +624 (774,324, .bin 786,360), RAM +56 on both (the queue's state in the driver object). Nearly all of it is the new send path (_sendQueued( ) 228, _sendPoll( ), _sendFinish( ) and enc28j60_frame_send_finish_blk( ) 100 each, _sendStartNext( ) 80, against sendFrame( ) -144 and enc28j60_frame_send_blk( ) -90); the /license page, whose third-party note names the new commit, 12. The seven radio images are byte for byte main's (192e1ad), compared by sha256. 2026-10-15 fix/wire-tft-flash-render-274: the WiFiServerSecure accept override (wifiserversecure_drop_plaintext.patch, patch.sh 2b-ter) drops a non-TLS client on the TLS port before the BearSSL handshake, decided from its first byte (#274). It is compiled wherever SIMUT_WEB_HTTPS is set, so the five HTTPS images grow: pico_wiretft +56 B (774,380, .bin 786,416), release +48 (1,022,516, .bin 1,034,548), test_https +48 (1,032,004), asserts +56 (1,024,820, .bin 1,036,852), pico2_w_release +24 (998,624, .bin 998,648). pico_wire, pico_w_test, alpha and air compile no HTTPS server, so the patched accept path is not in them and they keep main's sizes (d5f7063). 2026-10-15 perf/tft-spi-clk-peri: setup( ) clocks clk_peri from clk_sys on the six images that drive the panel and SIMUT_TFT_SPI_HZ is 66.5 MHz; /api/status gains sys.clk_peri and sys.tft_hz through macros, so the images without the panel compile the very tokens they did. Flash used (.bin): release +216 (1,022,732, .bin 1,034,764), test +208 (1,027,156, .bin 1,039,188), test_https +208 (1,032,212), asserts +208 (1,025,028, .bin 1,037,060), pico2_w_release +224 (998,848, .bin 998,872), wiretft +208 (774,588, .bin 786,624). pico_wire, alpha and air are byte for byte main's (80c3c88), compared by sha256. 2026-10-16 fix/injected-touch-never-ends: the injected touch (POST /api/touch, `touch sim`, `touch hold`) ends in loopCore1( ) right after handleTouch( ) instead of inside mapTouchPoint( ); the sensitivity screen's Cancelar takes an injection and records its provenance (_lastTouchInjected) before the accept, and the calibration's measuring phase ignores it, with simNow read once per handleTouch( ). Flash used (.bin): release +40 (1,022,772, .bin 1,034,804), test +40 (1,027,196, .bin 1,039,228), test_https +40 (1,032,252), asserts +40 (1,025,068, .bin 1,037,100), pico2_w_release +24 (998,872, .bin 998,896), wiretft +48 (774,636, .bin 786,672). The provenance store is 16 B of that on release, test, test_https, asserts and wiretft and 8 B on pico2_w_release. The same test placed before _rawTouchState, the change's first version, was 8 B smaller on release and test_https and the same on the other four; it released a tap unseen when the first Core 1 pass came later than its hold, so it was dropped. pico_wire, alpha and air come out the size of their records, flash used and .bin; they were not compared by sha256. 2026-10-18 fix/safe-reboot-writes-pending-log: safeReboot( ) writes the log records it holds in RAM (flushPendingIfAny( ) inside the pre-reboot hook's guard, in safeReboot( ) and in the RP2350's safeRebootFlashUpdate( )). Four images grow 8 B, the call: pico_w_test (1,027,204, .bin 1,039,236), pico_w_asserts (1,025,076, .bin 1,037,108), pico2_w_release (998,880, .bin 998,904) and pico_wire (592,124, .bin 604,160). pico_w_release, pico_w_test_https, pico_w_alpha, pico_w_air and pico_wiretft come out the size of their records, flash used and .bin, their alignment absorbing it; RAM unchanged. 2026-10-21 fix/radio-answers-by-return-code (#266, #282): a reconnect scan that started quickly and never finished asks the chip one read (radioRead( ), an antenna-setting ioctl) and goes by the driver's return code, a quick start no longer ends a silent streak, and the minute's RSSI sample and getRssi( ) read cyw43_wifi_get_rssi( )'s return code (readRssi( )) instead of the variable WiFi.RSSI( ) leaves unwritten. On main 7e3f29a6 (#281 in), the seven radio images grow: release +160 B (1,022,932, .bin 1,034,964), test +176 (1,027,380, .bin 1,039,412, 731 B of OTA headroom left), test_https +176 (1,032,428), asserts +160 (1,025,236, .bin 1,037,268), alpha +168 (976,180) and air +168 (1,019,512), both .bin the same, pico2_w_release +184 (999,064, .bin 999,088). The two wired images build no radio unit and are byte for byte main's (pico_wire sha256 f464769b, pico_wiretft e781ea41); RAM unchanged on all nine. 2026-10-21 fix/language-pack-log-records (#283): the language pack's records get their own tag (TAG_I18N, 13) and codes (620-623), the console text of the four carries only its detail, and the tags passed to the LOG_ macros are checked at compile time. On main 2f4bc3d3, the seven images that build the pack loader shrink: release -24 B (1,022,908, .bin 1,034,940), test -32 (1,027,348, .bin 1,039,380, 763 B of OTA headroom left), test_https -24 (1,032,404), asserts -24 (1,025,212, .bin 1,037,244), air -32 (1,019,480, the .bin the same), pico2_w_release -48 (999,016, .bin 999,040), wiretft -24 (774,612, .bin 786,648); their budgets come down. On release: findAndLoadLangFile( ) -92 (its two String concatenations), translateCodeEn( ) +52 (the four new cases), tagStringToId( ) and loadLangFile( ) +4 each, .rodata +8 (the four names against the shorter console texts); the name table moved from tagIdToString( )'s function-local static to LOG_TAG_NAMES, 64 B either way. The two images that do not build the loader grow, raising their budgets: pico_wire +184 (592,308, .bin 604,344: translateCodeEn( ) +52 and tagStringToId( ) +4 in .text, the four names +128 in .rodata) and alpha +56 (976,236, the .bin the same: .text +56, its .rodata absorbing the names in the padding before BTstack's sector-aligned TLV). RAM unchanged on all nine. The check itself costs nothing: the same tree with no static_assert, tagStringToId( ) inline and the old function-local table builds byte-identical images (release sha256 e971dfe8, air e5935de2, wiretft a01a20b2). 2026-10-22 fix/alpha-console-event-names: the alpha's two log lookups, logcodeLookup( ) and trlLookup( ) in DisplayManager_Alpha.cpp, answer nullptr where they answered \"\", which LogManager took as the translation. Each became `movs r0, #0; bx lr`, 4 B, where it loaded a literal, 8 B: pico_w_alpha -8 B (976,228, the .bin the same) and pico_wire -8 B (592,300, .bin 604,336), the two images that build that file. The seven others are byte for byte main's (25e169d), compared by sha256. RAM unchanged on all nine. 2026-10-22 chore/https-test-image-room: pico_w_test_https serves the license page from LittleFS too (custom_fs_pages ALARMS_PAGE, FILE_PAGE, TEL_PAGE and LICENSE_PAGE), the maintainer's option (a) for feat/ui-drivers' S10b-2, which grows this image about 160 B where its FLASH region had 44 B left (the last LOAD ended at 0x100FEFD4, readelf -l): -4,256 B (1,028,148, the .bin 1,040,180 and not recorded, ota_exempt), the region's room 4,300 B (the last LOAD ends at 0x100FDF34); its budget comes down. The license page is 4,260 B of gzip in this env. The other eight are byte for byte main's (a8ccf4c3), compared by sha256.", + "measured_at_commit": "2026-10-13 feat/wire-driver 4912762 (the seven radio images; the budgets only move here), feat/wire-surface, the log-code commit, and feat/net-boundary, B2 on 20c06b0 plus this change, then ebcf29e plus the review's fixes (pico_wire, pico_wiretft); feat/net-radio-unit on 3055b31 plus this change (all nine); fix/radio-link-in-ntp-wait on 53b6d7b plus this change (the seven radio images).; fix/silent-radio-no-blind-join on 2290638 plus this change (all nine).; fix/link-health-in-ntp-wait on 5293bae plus this change (all nine). measured is the zopfli image PlatformIO prints.; fix/web-short-write on f1b8b8f plus this change (all nine), built against a PlatformIO core that carries the override (PLATFORMIO_CORE_DIR, a hardlinked copy of ~/.platformio patched by patch.sh).; fix/web-fewer-writes on 686a1de plus this change (all nine), built against a PlatformIO core that carries overrides 2m and 2n (PLATFORMIO_CORE_DIR, a hardlinked copy of ~/.platformio patched by patch.sh).; deps/pico-enc28j60-1.3.1 on 192e1ad plus this change (all nine), built against ~/.platformio, which carries overrides 2m and 2n since 2026-10-15.; fix/wire-tft-flash-render-274 on d5f7063 plus this change (the five HTTPS images), built against ~/.platformio patched by patch.sh, which carries overrides 2m, 2n and the WiFiServerSecure accept patch (2b-ter).; perf/tft-spi-clk-peri on 80c3c88 plus this change (the six panel images), built against the ~/.platformio as main left it (its pico_w_release .bin matched the record to the byte before the change).; fix/injected-touch-never-ends on ea4fcb1 plus this change (all nine), built against the ~/.platformio as main left it (its pico_wiretft .bin matched the record to the byte before the change: 786,624 B, sha256 3aff19e8).; fix/safe-reboot-writes-pending-log on 90e82d1 plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.; fix/radio-answers-by-return-code rebased on 7e3f29a6 plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.; fix/language-pack-log-records on 2f4bc3d3 plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.; fix/alpha-console-event-names on 25e169df plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.; chore/https-test-image-room on a8ccf4c3 plus this change (all nine, from scratch), built against ~/.platformio, which carries every override main's patch.sh applies.", "ota_exempt": { "pico_w_test_https": "A bench image: the one with the full console and the TLS server together, for the HTTPS suites (AGENTS.md). It reaches the rig over USB, and release-ota.yml does not publish it. #232 (2026-10-02) left it 147 B under OTA_APP_SAFE_MAX_SIZE, and keeping it there meant cutting code the product images ship too, or moving more of its pages to LittleFS. Over the ceiling the device refuses to stage it, which costs only installing this image over the air; its flash budget still holds. Exempt since 2026-10-02 (docs/analysis/PLANO_STABLE.md, B6)." }, @@ -552,8 +552,8 @@ "bin": 1039380 }, "pico_w_test_https": { - "budget": 1032404, - "measured": 1032404 + "budget": 1028148, + "measured": 1028148 }, "pico_w_asserts": { "budget": 1025212, diff --git a/tools/generated/profiles.ini b/tools/generated/profiles.ini index 44d92338..3e1164c5 100644 --- a/tools/generated/profiles.ini +++ b/tools/generated/profiles.ini @@ -63,7 +63,7 @@ build_src_filter = ${pico_base.build_src_filter} lib_ignore = SerialBT custom_web_omit = slot -custom_fs_pages = ALARMS_PAGE, FILE_PAGE, TEL_PAGE +custom_fs_pages = ALARMS_PAGE, FILE_PAGE, TEL_PAGE, LICENSE_PAGE [env:pico_w_asserts] extends = pico_base