Skip to content

predictor dry run (measurement only) - #3

Open
lynt-smitka wants to merge 15 commits into
mainfrom
ci-language-predict-dryrun
Open

lynt-smitka wants to merge 15 commits into
mainfrom
ci-language-predict-dryrun

Conversation

@lynt-smitka

Copy link
Copy Markdown

Measurement run only, not for merging: the predictor branch plus one workflow line
setting LANGUAGE_PREDICT=dryrun, so every board builds all languages and prints the
prediction error for each of them (Predict check ...).

The skip run (#2) could only verify the 68 languages it actually built; the 1 484 it
skipped are unverified by construction. This run measures all of them.

4RH1T3CT0R7 and others added 15 commits September 5, 2026 01:05
The last buffer was padded by length_read % 4 bytes instead of
4 - length_read % 4, so a 5 or 7 byte tail still ended unaligned.
Round caller-supplied buffer halves down to a multiple of 4 so the
pad always fits, and add a unix coverage test.
C5 is the first dual-band ESP32. It differs from c6 in ways that build
cleanly but fail at run time:

- bootloader flash offset is 0x2000, not 0x0
- ADC1 channels start at GPIO1, not GPIO0
- efuse MAC registers are named like c61, not c6
- libphy.a references _rom_eco_version, so rom.version.ld must link
- USB-Serial-JTAG pads (GPIO13/14) are cleared by gpio_ll_func_sel(),
  so reset_all_pins() must skip them along with the flash/PSRAM MSPI
  pins and VDD_SPI
- boot button is GPIO28, not GPIO9 or GPIO0
- the 48MHz crystal leaves only 40/80/160/240MHz CPU valid
- TWAI is the newer TWAI-FD, so canio is off pending a backend
8MB flash, 8MB quad PSRAM, WS2812B on GPIO27, UART0 on GPIO11/12.

Flash mode is dio: qio locks the CPU during bootloader startup on this
board. PSRAM stays qio, which is the only mode C5 offers.
The comment was copied from the c6 block. The 8MB flash has a 2048K
app partition, and enabling both leaves 42 KB free.
The C5 has an I2S peripheral and the DevKitC breaks out 19 GPIOs, so
external I2S hardware works the same as on the S3 DevKitC, which ships
with these on and has no onboard audio either.

Costs 78160 bytes, leaving 42928 free in the 2048K app partition.
Seven ports never write firmware.size.json, so build_release_files.py cannot
tell whether the en_US build left room and builds all 17 languages for every
board of those ports on every pull request.

They cannot use this script as it stands: it reads the region size out of a
linker script, which needs the size to be a literal there. raspberrypi writes
LENGTH = firmware_size, a symbol the board can override; broadcom, cxd56 and
silabs link a script from a submodule or an SDK; zephyr-cp has no script of its
own at all.

The linker map has the same numbers with the symbols already resolved, and
every one of these ports either writes a map already or is one flag away from
it. So read the Memory Configuration table when the file has one, and keep the
linker script path for the ports that pass one. The region name is FLASH_FIRMWARE
or FLASH, or --region for anything else.

Wired into raspberrypi, renode, mimxrt10xx, broadcom, cxd56 and silabs, which
only needed -Wl,-Map added. A missing map or an unknown region name prints what
was found and writes nothing, so the language skip falls back to today's
behaviour instead of failing the build.

zephyr-cp still needs doing; its Makefile has none of the toolchain variables.
Its makefile has none of the toolchain variables the other ports get from
circuitpy_mkenv.mk, so there is no size(1) to pipe in. There does not need to
be: what the image occupies in flash is the size of the binary, which is how
ports/espressif has always measured it. Pass --image and the region still comes
from the map.

Measured on rpi_pico: 502256 bytes used of a 1040128 byte region, against the
502000 and 1040128 Zephyr prints itself -- the difference is the 256 byte
second stage, which the .bin includes and the FLASH region does not.
Rather than rounding each half of a caller-supplied buffer down to a
multiple of 4, reject lengths that are not a multiple of 8 up front so
the buffer the user passes is the buffer that gets used.
…padding

audiocore: fix WaveFile 8-bit sample padding at end of file
espressif: add ESP32-C5 support and the ESP32-C5-DevKitC-1-N8R8 board
Neither has a flash firmware region to measure against. cxd56 links the image
into RAM through the Spresense SDK script, so its map has one region and it is
called ram; broadcom boots kernel.img off an SD card and its regions are RAM and
READONLY. Nothing there constrains the firmware, so there is no headroom to
compute and the step only printed what it could not find.
atmel-samd, analog, litex, nordic and stm were still passing their linker
script, which left the script answering the same question two ways. Their maps
carry the same numbers -- the script computed them, ld resolved them -- so point
those five at the map as well and the linker script parser, the K and M suffix
handling and the eval that needed them all come out.

What a port supplies is now one rule: the map for the region, size(1) or --image
for what is used.
…fallback

build_release_files: read the linker memory table when size.json is missing
…em on PRs

On pull requests the translations other than en_US are built only to
prove that they still fit in flash. The compiled code is identical for
every translation; only three generated data files differ: the
compressed strings, the compression dictionary and the terminal font.

When the first language leaves less than 10 KB of headroom, run only
the generators (the make targets for translations-<lang>.c and
autogen_display_resources-<lang>.c, about 4 s, no compiler), count the
bytes of the generated tables and predict the flash usage. Only
translations predicted within LANGUAGE_MARGIN (1 KB) of the limit, or
whose build configuration differs (clean build), are really built.
LANGUAGE_PREDICT=dryrun builds everything and prints the prediction
error; LANGUAGE_PREDICT=off restores the old behaviour.

Measured on feather_m4_can, pybadge and metro_m4_express with every
language (41 predictions): error -5..+174 bytes, almost always an
over-estimate. On metro_m4_express the prediction flagged fr as not
fitting; the real build then overflowed by 56 bytes. feather_m4_can
board job: 443 s -> 228 s; the remainder is the two clean builds.
Push and release builds are unchanged.
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.

4 participants