Changelog
[v0.10.0]
Added
- Enum extension settings. A manifest extension setting can now be an enum (
kind = "enum"with a list ofchoicesand adefault), andbuildemits it as-D<FLAG>=<value>rather than the boolean-D<FLAG>=ON/OFF. The first use is the SQLite API selector that pairs with php-esp32 1.0'sext/sqlite3support:[extensions.sqlite] type = "pdo-sqlite" | "sqlite3"(defaultpdo-sqlite), passed as-DPHP_EXT_SQLITE_API. Interactiveinitoffers the choices; an invalid or absent value falls back to the setting's default, and the generated config keeps the chosen value. build --clean. Removes the build directory before building, to clear a poisoned CMake cache — a failed configure otherwise caches negative results (e.g. "compiler identification is unknown") and repeats them even after the environment is fixed. A build failure now also hints to retry with it.
Fixed
system-setupinstalls both toolchains. It raninstall.sh esp32p4, installing only the RISC-V toolchain; a later build for an ESP32-S3 board then failed withxtensa-esp32s3-elf-gcc ... not found in the PATH. It now installsesp32s3,esp32p4, covering both the Xtensa and RISC-V toolchains the firmware's boards need.system-setupre-pins ESP-IDF submodules on checkout. After checking out an IDF version it now runsgit submodule update --init --recursive, so the submodules match the pinned version instead of being left at stale commits (the cause of "target mbedcrypto is not built" when a stray mbedtls 4.x is checked out under an IDF that expects 3.6.x).- Clear error when the serial port isn't accessible.
flashandmonitornow check the port up front (viaaccess(2), without opening it, so the board isn't reset) and, on a permission failure, print the fix (sudo chmod a+rw <port>for now,sudo usermod -aG dialout $USERpermanently) instead of a crypticPath '/dev/ttyACM0' is not readablefrom esptool.
[v0.9.1]
Added
- Project name passed to the firmware.
buildnow emits-DPHP_ESP32_PROJECT_NAME=<name>(from the config'sname), which the firmware surfaces inphpinfo()'s new "PHP Baremetal Infos" table alongside the board and the php-esp32 / ESP-IDF versions.
[v0.9.0]
Added
phpflash partitions publish— writes apartitions.csvinto the project from the configured board's committed table, with guidance comments and a per-board table of sensiblefactorysizes. The table is computed from the board's flash size (read from itssdkconfig.board) and shows how much eachfactoryleaves for the generatedstorage/phpstorepartitions.--forceoverwrites an existing file;--php-esp32-pathpoints at the firmware checkout. See docs/recipes/custom-partition-table.md.- Per-project partition table. When a
partitions.csvsits next tophp-esp32.config.toml,buildpasses-DPHP_PARTITIONS_CSVand the firmware uses it as the fixed-partition spec instead of the board's committed table (the generatedstorage/phpstorepartitions are still appended). The build announcesusing project partition table; delete the file to revert to the board default. - Numeric extension settings. The config parser now accepts integer values under
[extensions.<name>](previously only booleans and strings were kept, so numbers were silently dropped). This lets the ESP32-S3 onboard-RGB extension take a pin:[extensions.s3_onboard_rgb] pin = 48, whichbuildpasses as-DPHP_S3_RGB_GPIO(default 48). The extension itself is read from the firmware manifest like any other, so nothing else changed here.
[v0.8.0]
Added
[web-server] init— a web-server project can name a PHP script the firmware runs once, before the HTTP server starts, for one-time setup shared across requests (bring hardware up, seed the in-RAMmem_*or persistentstore_*stores).buildpasses it as-DPHP_WEB_INITonly for aweb-serverproject with a non-emptyinit.initscaffolds a commented[web-server]section. See the firmware's mem.md.
[v0.7.0]
Added
discover --allunderstands boards with no microSD slot. The probe firmware now reportsmicrosd=n/afor an embedded-only board (e.g. the newesp32-*-zero), anddiscoverprints "microSD: n/a (this board has no card slot)" instead of treating it as an empty slot. Boards and their capabilities are still read from the installed php-esp32, so the new boards need no change here.
Fixed
discover --allboard identification when a slotless variant is a candidate. The final match now uses the microSD probe: a mounted card proves the board has a slot, which rules out the slotless-zerovariant and picks the board with a slot -- previously, adding a-zeroboard made the non-network candidate count ambiguous anddiscovergave up even though a card had mounted. When nothing is detected (no link, no card), it explains that a slotless-zeroboard and an SD board with an empty slot look identical, and that inserting a card settles it.
[v0.6.0]
Added
[storage] reserve_kb— for the firmware's dynamic partition table,buildpasses-DPHP_STORAGE_RESERVE_KBso an embedded project can pad its flashstoragepartition beyond the source (0 = just fit it). A microSD project has nostoragepartition, so the erase step on flash is now a no-op there (it was already tolerant of a missing partition)..envsupport — phpflash reads a project's.env(next tophp-esp32.config.toml), parses it (KEY=VALUE,#comments,export, single/double quotes) and bakes it into the firmware, where PHP exposes it as$_ENVandgetenv(). Configurable via[env](enabled, default on when the file exists;file, default.env).phpflash initnow adds.envto the scaffolded.gitignore. The values live in flash, not on the microSD -- not secret, but off removable media. See the firmware side in environment.md.[store] size_kb— sizes the firmware's reboot-persistent key-value store (store_*):buildpasses-DPHP_STORE_KB, and the dynamic partition table turns it into a dedicated NVS partition. 0 or absent means no persistence. See store.md.
[v0.5.0]
Added
- Per-project C extensions. A project's custom C extensions under
./firmware/exts/are compiled into the firmware:buildpasses-DPHP_PROJECT_EXTS_DIRwhen the directory exists (and holds at least one extension), otherwise nothing changes. See the firmware side in custom-extensions.md. phpflash ext new <name>— scaffold a custom C extension. It writesfirmware/exts/<name>/<name>.cwith a working skeleton (a module entry named<name>_module_entryplus two example functions), whichbuildthen compiles in. The name must be a valid lowercase C identifier;--forceoverwrites an existing file.
[v0.4.0]
Added
- Per-project PHP version —
[php] versioninphp-esp32.config.tomlpins the PHP language version to build (for example8.5.9), one of the versions installed undercomponents/php/versions/. Empty followsdefault_versionin the repo'sphp-esp32.toml, so existing configs are unaffected.phpflash initoffers the installed versions when there is more than one, and records the choice only when it differs from the default. A version that isn't installed fails the build up front with the list of the ones that are, instead of a late ESP-IDF error.
[v0.3.0]
Added
- Chip/board check before flashing —
phpflash flashprobes the connected chip and refuses to write an image built for a different target (for example an ESP32-S3 image onto a P4), with a message pointing at[board].target.--forceskips the check, and an inconclusive probe (no board yet, a busy port) never blocks — esptool remains the backstop that verifies the chip during the write. storagepartition wipe on a microSD flash — flashing amicrosd(non-embedded) project now erases a leftoverstoragepartition from an earlier embedded build, so a stale in-flash image can't mount and shadow the microSD.
Changed
- Pinned ESP-IDF target — the build passes
-DIDF_TARGETderived from the board's family, soidf.pynever infers the architecture from a stray in-sourcesdkconfig(which could silently build for the wrong chip when a config was left over from a different board). - Errors are reported as a single clean line: the root command sets
SilenceUsage/SilenceErrors, so a failed command no longer dumps usage or Cobra's own error trailer.
[v0.2.0]
Added
Project lifecycle
phpflash init [dir]— scaffold a project (php-esp32.config.toml,.gitignore,project-src/index.php). Interactive with a default for every prompt, or--yesfor defaults;--forceto overwrite. Board, storage/execution modes and optional extensions are read live from the installed php-esp32, offering only what the firmware implements and the chosen board supports.phpflash system-setup— install the prerequisites: ESP-IDF (clone/checkout +install.sh) and php-esp32 (clone/checkout +fetch-php.sh). Idempotent; updates an existing checkout in place.phpflash build— derive the deterministic-D<flag>=ON/OFFlist from php-esp32's manifest, run any required fetch scripts, then driveidf.pyinto a per-projectbuild/tree (isolated, side-by-side builds). Output rendered as phases with a compile progress bar; the raw ESP-IDF log is printed on failure.phpflash flash [-p port]/phpflash monitor [-p port]— flash and open the serial console. Port autodetection globs/dev/ttyACM*then/dev/ttyUSB*without opening any device.
Storage, networking and TLS
- Embedded storage —
storage_type = "embedded"builds the PHP source into a read-only image (-DPHP_EMBED_SRC); the board runs with no card.[storage] microsdopts an embedded project back into a card. - Static DNS —
[network] dns = [...]passed to the firmware as-DPHP_NET_DNS. - openssl configuration — for the full openssl build:
-DPHP_OPENSSL_CONFfrom[extensions.openssl] config_path;EnsureOpenSSLConfships a minimalopenssl.cnfwith the source so on-chip key generation works. - TLS client certificates — a full-openssl
tlsproject has its CA bundle provisioned from the host trust store intocerts_path(auto-detected source, orcerts_source), passed as-DPHP_TLS_CAFILE. phpflash update-certs— refresh that CA bundle, overwriting it with the current host trust store.
Board discovery
phpflash discover— identify the connected board from the board outwards (no project needed): list serial ports and their USB bridge, probe the chip with esptool (type, revision, flash, MAC, built-in radio), and map it to the supported boards. Reports an unsupported chip plainly.phpflash discover --all— actively probe a blank board's peripherals by flashing a small discovery firmware, built per candidate board (reusing that board'sboard.c, so it uses the real GPIO wiring), and name the match. Destructive (warns, confirms, reminds to re-flash);-y/--yesskips the prompt.
Configuration & integration
php-esp32.config.tomlschema:name,storage_type,type,[board],[esp-idf],[php-esp32],[storage],[network],[extensions.<name>](bool + string settings),[php].php-esp32.config.local.toml— optional, git-ignored overlay for machine-specific tweaks.- Path/version resolution: CLI flag → config → environment (
IDF_PATH,PHP_ESP32_DIR) → default. - Zero hard-coded hardware/extension knowledge: extensions, flags, settings, boards and modes
are all read from the installed php-esp32 at runtime (
php-esp32.toml, the per-versionmanifest.toml,board.toml/family.toml).scripts/check-manifest.pyin php-esp32 keeps the manifest in step with the build.
Packaging
- Single static Go binary; dependencies limited to
spf13/cobraandBurntSushi/toml. - Version stamped at build time via
-ldflags "-X phpflash/cmd.Version=<tag>"(--version). - Release workflow builds Linux
amd64/arm64, generatesSHA256SUMS, and publishes a GitHub release on av*tag.