Skip to content

Conversation

UncleGrumpy
Copy link
Collaborator

@UncleGrumpy UncleGrumpy commented May 22, 2024

These changes include several enhancements to the ESP32 build configuration and deployment of custom and test builds. The language flavor is determined by the offset of the main.avm partition in the partition table, simplifying Elixir supported builds and making the configuration of the image less error prone. The configuration of an Elixir build may be done without altering git tracked files by using idf.py -DAVM_ELIXIR_BOOT=on set-target ${CHIP}. This is the equivalent of setting the custom partition file name to partitions-elixir.csv using idf.py menuconfig. Other existing AtomVM configuration options have been added to main/Kconfig.projbuild and are exposed in idf.py menuconfig under the AtomVM menu to make the configuration process more natural for users already familiar with ESP-IDF and its build and configuration system.

The auto discovered flavor of the esp32boot (boot.avm partition) libraries are now included in the idf.py flash task. This makes use of the build/mkimage.sh script only necessary for building release images in the CI or to create a complete image for future use, and makes the experience like most other ESP-IDF based projects. To flash only the factory (AtomVM) partition idf.py app-flash may be used or idf.py bootloader-flash app-flash if changes made affect the bootloader partition as well.

Changes the build configuration for reproducible builds, this strips leading path information (which is replaced by placeholders), and allows locally building from a release tag and generating a binary with the same sha256 checksum as official release binaries (as long as ESP-IDF and toolchain versions match those used to build the release). See:
https://docs.espressif.com/projects/esp-idf/en/v5.5/esp32/api-guides/reproducible-builds.html

The nvs partition may now be generated and included in the build/mkimage.sh script (or flashed manually using the idf.py nvs-flash command) if the file nvs_partition.csv is present in the top level esp32 platform directory. An example is provided and nvs_partition.csv is added to .gitignore to prevent accidental pushes of sensitive passwords.

Closes atomvm/exatomvm#34

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

@UncleGrumpy UncleGrumpy changed the title Enhancements to esp32 build configuration improvements to esp32 build configuration May 27, 2024
@UncleGrumpy UncleGrumpy force-pushed the esp32_build_config branch 2 times, most recently from 1f1e6b3 to 492105f Compare June 6, 2024 01:43
@petermm
Copy link
Contributor

petermm commented Jun 10, 2024

Not sure I like this bundling of commands:

  1. Imho it's a coupling, implicit behaviour change - which might hinder future things, like point 2..

  2. In a simulator flow I use: idf.py build && touch ~/path_to_project/atomvm_wokwi_bins/flasher_args.json (as to build and then reboot sim) - and having mkimage in there would slow things down.

But I'm also a poweruser of idf.py build && ./build/mkimage.sh - so I get the drift, but not sure I understand how it simplifies deploying custom images..

Copy link
Collaborator

@bettio bettio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it is an addition that fills some kind of huge gap in v0.6 (or not), so regardless to the outcome of this discussion I would target main branch anyway.

@UncleGrumpy
Copy link
Collaborator Author

@petermm, I don’t want to disrupt anyone’s workflows. My goal was just to streamline the process for newer users who need to build a custom image to include additional components, like atomvm_mqtt. It makes more sense for me to add an additional cmake job called “deploy” (or similar) that will build the complete image and flash it to the target device using the generated ./build/flasjimage.sh script, leaving the default “build” task unchanged, this will better my goal and should have no affect on any pre-existing workflows.

@UncleGrumpy UncleGrumpy marked this pull request as draft June 14, 2024 15:40
@pguyot
Copy link
Collaborator

pguyot commented Jun 22, 2024

Should we keep a way to not create the image? (it's not much longer anyway). When working on the VM, I usually only reflash with idf.py flash which is faster than flashing the whole image.

Also, one of my workflows (la machine, obviously) does not include esp32boot.avm at all because it seems to me that esp32boot.avm doesn't bring anything to production images. I'll definitely work around this improvement for newcomers, though.

Likewise, qemu-based tests only use artifacts created by idf.py build (the VM, the partition map and the bootloader) and not the full image.

@UncleGrumpy
Copy link
Collaborator Author

UncleGrumpy commented Jun 23, 2024

Should we keep a way to not create the image?

I converted this back to draft, because I realize after @petermm’s comments that could be intrusive on existing workflows, so instead I will create and document a new build task that can be used as an alternative to idf.py build that will create the ready to deploy image, or even flash the image after building so that flashing a new custom image can be achieved with one command.

@pguyot
Copy link
Collaborator

pguyot commented Jun 23, 2024

Should we keep a way to not create the image?

I converted this back to draft, because I realize after @petermm’s comments that could be intrusive on existing workflows, so instead I will create and document a new build task that can be used as an alternative to idf.py build that will create the ready to deploy image, or even flash the image after building so that flashing a new custom image can be achieved with one command.

This sounds like a better approach indeed and would be very welcome. I also find it frustrating to have to call the bash script to build the image when I need it.

@UncleGrumpy UncleGrumpy force-pushed the esp32_build_config branch 2 times, most recently from 4b03b64 to 1901da0 Compare July 14, 2025 02:30
@UncleGrumpy UncleGrumpy changed the base branch from release-0.6 to main July 14, 2025 02:31
@UncleGrumpy UncleGrumpy force-pushed the esp32_build_config branch 4 times, most recently from f14c91d to 3923bf8 Compare July 22, 2025 16:32
@UncleGrumpy UncleGrumpy marked this pull request as ready for review July 23, 2025 03:21
@UncleGrumpy
Copy link
Collaborator Author

Should we keep a way to not create the image? (it's not much longer anyway). When working on the VM, I usually only reflash with idf.py flash which is faster than flashing the whole image.

I backed out of assembling the complete image as part of the build process, and it is no longer needed for most users. Instead I added flashing the correct flavor of esp32boot.avm to the idf.py flash task. Images can still be created for releases, or if users want to generate a portable image for future use.

In the case of reflashing during development work idf.py app-flash may be used to reflash only the AtomVM binary to the factory partiton. If flashing an updated bootloader is required, this may be accomplished using idf.py bootloader-flash (or combined with app-flash if necessary). This should actually save you a little more time since this does not include the partition map (which is unlikely to be changed often) that is also included when using idf.py flash.

At this point, you can run `idf.py flash` to upload the 3 binaries up to your ESP32 device, and in some development scenarios, this is a preferable shortcut.
At this point, you can run `idf.py flash` and have a complete working image. In some development
scenarios is may be helpful to use `idf.py app-flash` or `idf.py bootloader-flash app-flash` to
avoid re-flashing the entire image if no changes were made to the Erlang or Elixir libraries, and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by the naming of app-flash, and what it actually does..
avoid re-flashing the entire image if no changes were made to the Erlang or Elixir libraries

Copy link
Collaborator Author

@UncleGrumpy UncleGrumpy Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app-flash is an IDF included task, I did not have a choice there. It only flashed the esp-idf application - in this case that is the AtomVM binary. Perhaps I should explain the name of this task in the documentation, and that it is a native IDF task.

Copy link
Contributor

@petermm petermm Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gotcha, but most unfortunate name in our context, almost feels like we should add this to cmakelists:

add_custom_target(libatomvm-flash)
add_dependencies(libatomvm-flash app-flash)

and maybe add eavmlib/exavmlib to this sentence..
avoid re-flashing the entire image if no changes were made to the Erlang(eavmlib) or Elixir (exavmlib) libraries

I'm assuming app-flash flashes libatomvm..

Copy link
Collaborator Author

@UncleGrumpy UncleGrumpy Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It refers to the esp-idf application, app-flash means flash build/atomvm-{target-chip}.bin, which is the AtomVM executable with libatomvm statically linked in, not the atomvmlib.avm packed BEAM files. To flash those the documentation already describes using build/flash.sh -l ../../../build/libs/esp32boot/esp32boot.avm.

Copy link
Collaborator Author

@UncleGrumpy UncleGrumpy Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To put it another way, it is the contents of the factory partition.

I think when you think of it in terms of ESP-IDF app-flash is a very natural name for it. It just doesn't match an application in terms of AtomVM, but I don't think anyone is expecting to flash their beam application with esp-idf tools.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this section, hopefully it is more clear now.

@petermm
Copy link
Contributor

petermm commented Jul 24, 2025

This is great.

  1. I'm confused by the app-flash naming and meaning, is it flashing the runtime/vm? should it be named runtime-flash or vm-flash?

  2. I believe, that doing a set-target, automatically includes the reconfigure, eg. idf.py set-target esp32 reconfigure doesn't need a reconfigure, and it wastes time/cpu - in general the reconfigure is kinda confusing as it removes your changes in menuconfig.. for beginners this is not obvious, my point being not having a single mention of reconfigure might be beneficial.

@petermm
Copy link
Contributor

petermm commented Jul 24, 2025

also the simtest/wokwi ci will need some minor adjustment..

@UncleGrumpy
Copy link
Collaborator Author

UncleGrumpy commented Jul 24, 2025

also the simtest/wokwi ci will need some minor adjustment..

We don’t test Elixir in the simtest, and it has its own sdkconfig.defaults, so I don’t see any chances that need to be made… what did I miss?

Also note that the old method of copying the partitions-elixir.csv to partitions.csv still works, so if Elixir tests are added to simtest that is a viable option for the CI to use.

@UncleGrumpy
Copy link
Collaborator Author

  1. I believe, that doing a set-target, automatically includes the reconfigure, eg. idf.py set-target esp32 reconfigure doesn't need a reconfigure, and it wastes time/cpu - in general the reconfigure is kinda confusing as it removes your changes in menuconfig.. for beginners this is not obvious, my point being not having a single mention of reconfigure might be beneficial.

You are absolutely correct. Thank you! Not sure why I was keeping the reconfigure task. Simply set-target and include the Elixir support option is much cleaner and faster.

@petermm
Copy link
Contributor

petermm commented Jul 24, 2025

also the simtest/wokwi ci will need some minor adjustment..

We don’t test Elixir in the simtest, and it has its own sdkconfig.defaults, so I don’t see any chances that need to be made… what did I miss?

you are correct, pardon the brainlapse - we probably want tests to mimic "real" builds as much as possible, but let's align in subsequent PR..

@UncleGrumpy UncleGrumpy force-pushed the esp32_build_config branch 4 times, most recently from 89ca922 to 9ce9436 Compare July 25, 2025 03:31
@UncleGrumpy UncleGrumpy requested a review from bettio August 12, 2025 01:01
UPDATING.md Outdated
- ESP32 builds with Elixir support may be configured without making changes to git tracked files
using `idf.py -DATOMVM_ELIXIR_SUPPORT=on set-target ${CHIP}` instead of copying
partitions-elixir.csv to partitions.csv. This configures the build to use partitions-elixir.csv for
the partition table. The `boot.avm` offset in the partition table will determine which flavor of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

believe it's main.avm offset that determines flavor - or boot.avm size

Copy link
Collaborator Author

@UncleGrumpy UncleGrumpy Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! It should be main.avm, I think I was mentally rephrasing this as I was typing and ended up with the wrong partition there.

Fixed now.

Exposes the settable build options for the ESP32 platform to the `idf.py menuconfig` utility,
allowing for a more natural configuration experience for those already accustomed to the ESP-IDF
development environment.

Signed-off-by: Winford <[email protected]>
Changes GetVersion.cmake to allow use by platforms other than generic_unix, by allowing the cmake
include of version.cmake before including GetVersion.cmake on other platforms.

Fix version reporting for ESP32 builds when executing mkimage.sh by including the
AtomVM/version.cmake and AtomVM/CMakeModules/GetVersion.cmake files to be able to get the correct
version number when reporting build information during build/mkimage.sh execution.

Signed-off-by: Winford <[email protected]>
Change the script to exit after printing the help, instead of erroneously reporting that the image
was successfully created.

Signed-off-by: Winford <[email protected]>
Modifies the ESP32 build configuration and mkimage tool to automatically detect the image flavor
based on the partition table used. By checking the offset of the application partition the correct
flavor of language support is used when creating images. Adds a config option to configure an
Elixir supported build by using `idf.py -DAVM_ELIXIR_BOOT=on set-target ${CHIP}`.

Signed-off-by: Winford <[email protected]>
Adds the esp32boot library flavor (determined from partition table) to the idf.py flash job,
allowing developers to simply skip running mkimage.sh and flashimage.sh from the build directory
to flash all of the necessary partitions for a complete install to their device.

Signed-off-by: Winford <[email protected]>
Adds the option to provision nvs partition data at build time for the esp32 platform. If the file
`nvs_partition.csv` is found in the AtomVM/src/platforms/esp32 directory when building; the nvs
partition will be created and added to the `idf.py flash` task as well as to the configuration for
the mkimage.sh script in the build directory. An example file is provided and `nvs_partition.csv`
is added to `.gitignore` to prevent accidentally pushing secrets to remote repositories.

Signed-off-by: Winford <[email protected]>
Use reproducible builds for ESP32 platform so that locally build binaries will be an exact match
of release binaries for the same tag. Error message line info will start from the source path,
trimming any diectories leading up to it. SHA256 sums of binaries built from release tags should be
an exact match of release binaries.

Signed-off-by: Winford <[email protected]>
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