tools/espressif: Add UF2 output support

Add UF2 file output support for Espressif devices

Signed-off-by: Eren Terzioglu <eren.terzioglu@espressif.com>
This commit is contained in:
Eren Terzioglu 2026-01-05 12:01:09 +01:00 committed by Matteo Golin
parent 6bba29a2ba
commit be257fb910
5 changed files with 154 additions and 48 deletions

View file

@ -349,6 +349,13 @@ endef
endif
endif
# MAKEUF2 -- Merge raw binary files into uf2 format
define MAKEUF2
esptool.py -c $(CHIP_SERIES) merge_bin --format uf2 -o nuttx.merged.uf2 -fs $(FLASH_SIZE) -fm $(FLASH_MODE) $(ESPTOOL_BINS)
$(Q) echo "Generated: nuttx.merged.uf2"
endef
# POSTBUILD -- Perform post build operations
define POSTBUILD
@ -356,6 +363,7 @@ define POSTBUILD
$(if $(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT),$(call MAKE_VIRTUAL_EFUSE_BIN))
$(if $(CONFIG_ESP32_SECURE_FLASH_ENC_ENABLED),$(call FLASH_ENC))
$(if $(CONFIG_ESP32_MERGE_BINS),$(call MERGEBIN))
$(if $(UF2),$(call MAKEUF2))
endef
# ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py
@ -373,5 +381,12 @@ define FLASH
$(if $(CONFIG_ESP32_SECURE_FLASH_ENC_ENABLED),$(call BURN_EFUSES))
$(eval ESPTOOL_OPTS := -c esp32 -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) $(ESPTOOL_RESET_OPTS))
esptool.py $(ESPTOOL_OPTS) write_flash $(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS)
$(Q) if [ -z $(UF2) ]; then \
esptool.py $(ESPTOOL_OPTS) write_flash $(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS); \
else \
echo "Flashing using UF2 file."; \
cp nuttx.merged.uf2 $(ESPTOOL_PORT); \
sync; \
fi
endef

View file

@ -317,6 +317,13 @@ endef
endif
endif
# MAKEUF2 -- Merge raw binary files into uf2 format
define MAKEUF2
esptool.py -c $(CHIP_SERIES) merge_bin --format uf2 -o nuttx.merged.uf2 -fs $(FLASH_SIZE) -fm $(FLASH_MODE) $(ESPTOOL_BINS)
$(Q) echo "Generated: nuttx.merged.uf2"
endef
# POSTBUILD -- Perform post build operations
define POSTBUILD
@ -324,6 +331,7 @@ define POSTBUILD
$(if $(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT),$(call MAKE_VIRTUAL_EFUSE_BIN))
$(if $(CONFIG_ESP32S2_SECURE_FLASH_ENC_ENABLED),$(call FLASH_ENC))
$(if $(CONFIG_ESP32S2_MERGE_BINS),$(call MERGEBIN))
$(if $(UF2),$(call MAKEUF2))
endef
# ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py
@ -341,5 +349,13 @@ define FLASH
$(if $(CONFIG_ESP32S2_SECURE_FLASH_ENC_ENABLED),$(call BURN_EFUSES))
$(eval ESPTOOL_OPTS := -c esp32s2 -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) $(ESPTOOL_RESET_OPTS) $(if $(CONFIG_ESP32S2_ESPTOOLPY_NO_STUB),--no-stub))
esptool.py $(ESPTOOL_OPTS) write_flash $(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS)
$(Q) if [ -z $(UF2) ]; then \
esptool.py $(ESPTOOL_OPTS) write_flash $(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS); \
else \
echo "Flashing using UF2 file."; \
cp nuttx.merged.uf2 $(ESPTOOL_PORT); \
sync; \
fi
endef

View file

@ -282,6 +282,13 @@ define MKIMAGE
endef
endif
# MAKEUF2 -- Merge raw binary files into uf2 format
define MAKEUF2
esptool.py -c $(CHIP_SERIES) merge_bin --format uf2 -o nuttx.merged.uf2 -fs $(FLASH_SIZE) -fm $(FLASH_MODE) $(ESPTOOL_BINS)
$(Q) echo "Generated: nuttx.merged.uf2"
endef
# PREBUILD -- Perform pre build operations
ifeq ($(CONFIG_BUILD_PROTECTED),y)
@ -299,6 +306,7 @@ define POSTBUILD
$(if $(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT),$(call MAKE_VIRTUAL_EFUSE_BIN))
$(if $(CONFIG_ESPRESSIF_SECURE_FLASH_ENC_ENABLED),$(call FLASH_ENC))
$(if $(CONFIG_ESP32S3_MERGE_BINS),$(call MERGEBIN))
$(if $(UF2),$(call MAKEUF2))
endef
# ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py
@ -315,5 +323,12 @@ define FLASH
fi
$(if $(CONFIG_ESPRESSIF_SECURE_FLASH_ENC_ENABLED),$(call BURN_EFUSES))
$(eval ESPTOOL_OPTS := -c esp32s3 -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) $(if $(CONFIG_ESP32S3_ESPTOOLPY_NO_STUB),--no-stub))
esptool.py $(ESPTOOL_OPTS) write_flash $(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS)
$(Q) if [ -z $(UF2) ]; then \
esptool.py $(ESPTOOL_OPTS) write_flash $(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS); \
else \
echo "Flashing using UF2 file."; \
cp nuttx.merged.uf2 $(ESPTOOL_PORT); \
sync; \
fi
endef

View file

@ -262,6 +262,13 @@ define MKIMAGE
endef
endif
# MAKEUF2 -- Merge raw binary files into uf2 format
define MAKEUF2
esptool.py -c $(CHIP_SERIES) merge_bin --format uf2 -o nuttx.merged.uf2 -fs $(FLASH_SIZE) -fm $(FLASH_MODE) $(ESPTOOL_BINS)
$(Q) echo "Generated: nuttx.merged.uf2"
endef
# POSTBUILD -- Perform post build operations
define POSTBUILD
@ -269,6 +276,7 @@ define POSTBUILD
$(if $(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT),$(call MAKE_VIRTUAL_EFUSE_BIN))
$(if $(CONFIG_ESPRESSIF_SECURE_FLASH_ENC_ENABLED),$(call FLASH_ENC))
$(if $(CONFIG_ESPRESSIF_MERGE_BINS),$(call MERGEBIN))
$(if $(UF2),$(call MAKEUF2))
endef
# ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py
@ -287,5 +295,12 @@ define FLASH
$(if $(CONFIG_ESPRESSIF_SECURE_FLASH_ENC_ENABLED),$(call BURN_EFUSES))
$(eval ESPTOOL_OPTS := -c $(CHIP_SERIES) -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) $(if $(CONFIG_ESPRESSIF_ESPTOOLPY_NO_STUB),--no-stub))
$(eval WRITEFLASH_OPTS := $(if $(CONFIG_ESPRESSIF_MERGE_BINS),$(ESPTOOL_WRITEFLASH_OPTS) 0x0 nuttx.merged.bin,$(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS)))
esptool.py $(ESPTOOL_OPTS) write_flash $(WRITEFLASH_OPTS)
$(Q) if [ -z $(UF2) ]; then \
esptool.py $(ESPTOOL_OPTS) write_flash $(WRITEFLASH_OPTS); \
else \
echo "Flashing using UF2 file."; \
cp nuttx.merged.uf2 $(ESPTOOL_PORT); \
sync; \
fi
endef

View file

@ -27,6 +27,10 @@
# (contains .config and nuttx ELF) SOURCE_DIR - CMake source directory
# (NuttX root)
#
# Optional (matches make UF2=1): UF2 - If set to 1/on/yes/true, run
# MAKEUF2 (esptool merge_bin --format uf2). May also be set via the UF2
# environment variable when invoking cmake -P.
#
# All CONFIG_* variables are automatically loaded from .config file.
# ##############################################################################
@ -58,6 +62,22 @@ nuttx_export_kconfig(${DOTCONFIG})
include(${SOURCE_DIR}/tools/espressif/espressif_esptool_common.cmake)
# ##############################################################################
# UF2 output (tools/espressif/Config.mk MAKEUF2; make UF2=1)
# ##############################################################################
if(NOT DEFINED UF2)
set(UF2 "$ENV{UF2}")
endif()
set(UF2_ENABLED FALSE)
if(NOT "${UF2}" STREQUAL "")
string(TOLOWER "${UF2}" _uf2_lower)
if(_uf2_lower MATCHES "^(1|on|yes|true|y)$")
set(UF2_ENABLED TRUE)
endif()
endif()
# ##############################################################################
# Find required tools for the post build process
# ##############################################################################
@ -271,6 +291,53 @@ if(CONFIG_ESPRESSIF_SECURE_FLASH_ENC_ENABLED)
endif()
endif()
# ##############################################################################
# Set address/bin variable for esptool
# ##############################################################################
set(ESPTOOL_BINS "")
if(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT)
# MCUboot configuration
if(EXISTS "${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
message(
STATUS
"Merge bin: ${BL_OFFSET} -> ${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
list(APPEND ESPTOOL_BINS ${BL_OFFSET}
"${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
else()
message(FATAL_ERROR "mcuboot-${CHIP_SERIES}.bin not found in ${SOURCE_DIR}")
endif()
# Create empty vefuse.bin if it doesn't exist
if(NOT EXISTS "${BINARY_DIR}/vefuse.bin")
file(WRITE "${BINARY_DIR}/vefuse.bin" "")
endif()
list(APPEND ESPTOOL_BINS ${EFUSE_OFFSET} "${BINARY_DIR}/vefuse.bin")
message(STATUS "Merge bin: ${EFUSE_OFFSET} -> ${BINARY_DIR}/vefuse.bin")
list(APPEND ESPTOOL_BINS ${MCUBOOT_APP_OFFSET} "${BINARY_DIR}/nuttx.bin")
message(STATUS "Merge bin: ${MCUBOOT_APP_OFFSET} -> ${BINARY_DIR}/nuttx.bin")
if(CONFIG_ESPRESSIF_SECURE_FLASH_ENC_ENABLED AND CONFIG_ESPRESSIF_SPIFLASH)
list(APPEND ESPTOOL_BINS ${CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET}
"${BINARY_DIR}/enc_mtd.bin")
message(
STATUS
"Merge bin: ${CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET} -> ${BINARY_DIR}/enc_mtd.bin"
)
endif()
elseif(CONFIG_ESPRESSIF_SIMPLE_BOOT)
# Simple boot: same base offset as BL_OFFSET (0x2000 on ESP32-P4, else 0x0)
list(APPEND ESPTOOL_BINS ${BL_OFFSET} "${BINARY_DIR}/nuttx.bin")
else()
# Legacy boot: application at offset 0
list(APPEND ESPTOOL_BINS 0x0000 "${BINARY_DIR}/nuttx.bin")
endif()
# ##############################################################################
# Merge binaries (optional)
# ##############################################################################
@ -283,50 +350,6 @@ if(CONFIG_ESPRESSIF_MERGE_BINS)
endif()
# Build the list of binaries to merge Format: offset1 file1 offset2 file2 ...
set(ESPTOOL_BINS "")
if(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT)
# MCUboot configuration
if(EXISTS "${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
message(
STATUS
"Merge bin: ${BL_OFFSET} -> ${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
list(APPEND ESPTOOL_BINS ${BL_OFFSET}
"${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
else()
message(
FATAL_ERROR "mcuboot-${CHIP_SERIES}.bin not found in ${SOURCE_DIR}")
endif()
# Create empty vefuse.bin if it doesn't exist
if(NOT EXISTS "${BINARY_DIR}/vefuse.bin")
file(WRITE "${BINARY_DIR}/vefuse.bin" "")
endif()
list(APPEND ESPTOOL_BINS ${EFUSE_OFFSET} "${BINARY_DIR}/vefuse.bin")
message(STATUS "Merge bin: ${EFUSE_OFFSET} -> ${BINARY_DIR}/vefuse.bin")
list(APPEND ESPTOOL_BINS ${MCUBOOT_APP_OFFSET} "${BINARY_DIR}/nuttx.bin")
message(
STATUS "Merge bin: ${MCUBOOT_APP_OFFSET} -> ${BINARY_DIR}/nuttx.bin")
if(CONFIG_ESPRESSIF_SECURE_FLASH_ENC_ENABLED AND CONFIG_ESPRESSIF_SPIFLASH)
list(APPEND ESPTOOL_BINS ${CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET}
"${BINARY_DIR}/enc_mtd.bin")
message(
STATUS
"Merge bin: ${CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET} -> ${BINARY_DIR}/enc_mtd.bin"
)
endif()
elseif(CONFIG_ESPRESSIF_SIMPLE_BOOT)
# Simple boot: same base offset as BL_OFFSET (0x2000 on ESP32-P4, else 0x0)
list(APPEND ESPTOOL_BINS ${BL_OFFSET} "${BINARY_DIR}/nuttx.bin")
else()
# Legacy boot: application at offset 0
list(APPEND ESPTOOL_BINS 0x0000 "${BINARY_DIR}/nuttx.bin")
endif()
# Execute merge_bin
execute_process(
@ -342,3 +365,25 @@ if(CONFIG_ESPRESSIF_MERGE_BINS)
message(STATUS "Generated: nuttx.merged.bin")
file(APPEND "${BINARY_DIR}/nuttx.manifest" "nuttx.merged.bin\n")
endif()
# ##############################################################################
# UF2 image (optional; Config.mk MAKEUF2)
# ##############################################################################
if(UF2_ENABLED)
message(STATUS "MAKEUF2: Creating UF2 flash image")
execute_process(
COMMAND
${ESPTOOL} -c ${CHIP_SERIES} merge-bin --format uf2 -o
${BINARY_DIR}/nuttx.merged.uf2 -fs ${FLASH_SIZE} -fm ${FLASH_MODE}
${ESPTOOL_BINS}
RESULT_VARIABLE MAKEUF2_RESULT
WORKING_DIRECTORY ${BINARY_DIR})
if(NOT MAKEUF2_RESULT EQUAL 0)
message(FATAL_ERROR "esptool merge-bin --format uf2 failed")
endif()
message(STATUS "Generated: nuttx.merged.uf2")
endif()