LP firmware development
LP firmware uses the ESP-IDF environment described in Build from source. Linux loads its ELF through remoteproc after the root filesystem becomes available.
Build and install
From the parent project root:
make lp-firmware
make rootfs
The LP build creates
out/lp/esp-idf/main/s31_lp_main/s31_lp_main.elf and stages it as
out/staging/overlay/lib/firmware/esp32s31/s31-lp-core.elf.
The rootfs build packages that file. See the LP Makefile.
For an on-board replacement, first transfer the new ELF to
/tmp/s31-lp-core.elf, then stop LP before replacing the installed firmware:
/etc/init.d/S02s31-lp stop
cp /tmp/s31-lp-core.elf /lib/firmware/esp32s31/s31-lp-core.elf
/etc/init.d/S02s31-lp start
s31-lpctl status
s31-lpctl ping
The service locates remoteproc by the name esp32s31-lp, starts it and waits
for READY. status should include ready=1; ping reports a round-trip value
in microseconds. If startup fails, read dmesg and the service error before
attempting sleep. See S02s31-lp.
Keep firmware within its memory budget
The current ESP-IDF configuration reserves 8192 bytes (8 KiB) for LP
firmware. LP SRAM spans 0x2E000000–0x2E008000, but the entire 32 KiB is not
available to code, data and stacks:
Region |
Address range, end exclusive |
Role |
|---|---|---|
LP firmware allocation |
|
Current 8 KiB build budget |
OpenSBI suspend snapshot |
|
20 KiB reserved runtime snapshot |
Sleep-control reservation |
|
Final 1 KiB; current structure occupies 112 bytes |
Inspect ELF load segments and the linker map when increasing code, data or stack sizes. Do not expand into either shared reservation. See the build allocation, OpenSBI snapshot and memory map.
Change the protocol coherently
shared/s31_lp_protocol.h includes Linux’s
include/linux/soc/espressif/esp32s31-lp-protocol.h. LP publishes READY at
startup, validates requests, and writes response fields before the response
CRC. The current Linux, LP and OpenSBI sources agree on ABI 1 and the 28-word
layout.
When changing message codes, fields, states or CRC coverage, update all three consumers together and run the existing checks from the parent root:
python -m unittest tools.tests.test_s31_feature_contracts.DriverContracts.test_lp_sleep_abi_matches_opensbi tools.tests.test_s31_feature_contracts.DriverContracts.test_lp_mem_timer_starts_after_hp_asleep -v
These checks compare source contracts; they do not execute a suspend cycle. The LP reference owns the wire-format and field details, and Power management describes the retention path.
Add an LP peripheral
Before using a new register window, add its required LP peripheral-PMS access
in the remoteproc driver. The existing grant helper checks locked permissions
and verifies the written access bits; failure returns -EACCES. See
permission setup.
GPIO wake uses RTCIO ownership, level sampling and a configured LP GPIO
wakeup interrupt/ISR. The poll path covers the transition window; the ISR
records a GPIO reason and requests APPWR wake after HP_ASLEEP. Preserve the
inactive-at-ARM check and the cleanup that disables pulls, wakeup and input
before returning ownership. See GPIO handling and
ARM setup.