ESP TinyUF2
esp_tinyuf2
is an enhanced version of TinyUF2 for ESP chips with USB support. Which features:
support over-the-air (OTA) updates through the virtual USB drive
support dumping NVS key-value pairs to ini file in the virtual USB drive
support modify ini file and write back to NVS
UF2 is a file format developed by Microsoft for PXT, that is particularly suitable for flashing microcontrollers over MSC (Mass Storage Class). For a more friendly explanation, check out the blog post.
Support UF2 OTA/NVS in Your Project
Add the component to your project using
idf.py add_dependency
command.idf.py add-dependency "esp_tinyuf2"
Customer your partition table. Like other OTA solutions, you need to reserve at least two OTA app partitions. Please refer to Partition Tables and usb_uf2_ota example for details.
# Partition Table Example # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, , 0x4000, otadata, data, ota, , 0x2000, phy_init, data, phy, , 0x1000, ota_0, app, ota_0, , 1500K, ota_1, app, ota_1, , 1500K,
Using
idf.py menuconfig
to config the component’s behavior in(Top) → Component config → TinyUF2 Config
USB Virtual Disk size(MB)
: The size of the virtual U-disk shows in File Explorer, 8MB by defaultMax APP size(MB)
: Maximum APP size, 4MB by defaultFlash cache size(KB)
: Cache size used for writing Flash efficiently, 32KB by defaultUSB Device VID
: Espressif VID (0x303A) by defaultUSB Device PID
: Espressif test PID (0x8000) by default, refer esp-usb-pid to apply new.USB Disk Name
: The name of the virtual U-disk shows in File Explorer,ESP32Sx-UF2
by defaultUSB Device Manufacture
:Espressif
by defaultProduct Name
:ESP TinyUF2
by defaultProduct ID
:12345678
by defaultProduct URL
: Aindex
file will be added to the U-disk, users can click to goto the webpage,https://products.espressif.com/
by defaultUF2 NVS ini file size
: Theini
file size prepares for NVS function
Install tinyuf2 function like below, for more details, please refer example usb_uf2_nvs and usb_uf2_ota
/* install UF2 OTA */ tinyuf2_ota_config_t ota_config = DEFAULT_TINYUF2_OTA_CONFIG(); ota_config.complete_cb = uf2_update_complete_cb; /* disable auto restart, if false manual restart later */ ota_config.if_restart = false; /* install UF2 NVS */ tinyuf2_nvs_config_t nvs_config = DEFAULT_TINYUF2_NVS_CONFIG(); nvs_config.part_name = "nvs"; nvs_config.namespace_name = "myuf2"; nvs_config.modified_cb = uf2_nvs_modified_cb; esp_tinyuf2_install(&ota_config, &nvs_config);
Run
idf.py build flash
for the initial download, lateridf.py uf2-ota
can be used to generate newuf2
app binDrag and drop UF2 format file to the disk, to upgrade to new
uf2
app bin

Enable UF2 USB Console
Through menuconfig (Top) → Component config → TinyUF2 Config → Enable USB Console For log
, the log will be output to the USB Serial port (Output to UART by default).
Build APP to UF2 format
The new command idf.py uf2-ota
is added by this component, which can be used to build the APP to UF2 format. After the build is complete, the UF2 file (${PROJECT_NAME}.uf2
) will be generated in the current project
directory.
idf.py uf2-ota
Convert Existing APP to UF2 Format
To convert your existing APP binary to UF2 format, simply use the uf2conv.py on a .bin
file, specifying the family id as ESP32S2
, ESP32S3
or their magic number as follows. And you must specify the address of 0x00 with the -b
switch, the tinyuf2 will use it as offset to write to the OTA partition.
convert as follows
using:
uf2conv.py your_firmware.bin -c -b 0x00 -f ESP32S3
or:
uf2conv.py your_firmware.bin -c -b 0x00 -f 0xc47e5767
Note
To use the UF2 OTA function continuously, the TinyUF2 function must be enabled in the updated APP.
Using UF2 in Bootloader
By embedding a specific APP bin with UF2 functionality into the Bootloader, the following features can be achieved:
1. Automatically enter UF2 download mode when the factory/test/ota
partitions do not contain firmware.
2. Manually enter UF2 download mode by pulling the BOOT_UF2
pin low.
3. Manually enter UF2 download mode by calling esp_restart_from_tinyuf2() function in user app.
Example
Instructions:
By default, only
nvs/phy_init/factory
partitions are supported. To supporttest/ota/spiffs
partitions, modify the partition table manually and recompile.Drag-and-drop upgrades default to the
factory
partition. Ensure thefactory
partition exists or modify the code manually.The default
CONFIG_PARTITION_TABLE_OFFSET
is set to 0x60000. If the firmware is too large, modify this value.The default
nvs
partition name isCONFIG_BOOTLOADER_UF2_NVS_PART_NAME
(“nvs”), and the default NVS namespace isCONFIG_BOOTLOADER_UF2_NVS_NAMESPACE_NAME
(“uf2_nvs”). Ensure the user firmware uses the same NVS partition name and namespace as the bootloader for proper functionality.A working indicator LED is supported by default. The default LED GPIO is
CONFIG_BOOTLOADER_UF2_LED_INDICATOR_GPIO_NUM
(2). Ensure this matches the hardware connection.
Flash Partition Reference:
Notes
The
Bootloader UF2
bin must be flashed at an address aligned to a multiple ofCONFIG_MMU_PAGE_SIZE
; otherwise, it will not work.
Note: The CONFIG_MMU_PAGE_SIZE
for ESP32-S2/ESP32-S3/ESP32-P4 defaults to 64KB (0x10000), so flashing must align to a 64KB (0x10000) boundary.
Configure
CONFIG_PARTITION_TABLE_OFFSET
to accommodate the combined size ofbootloader.bin + bootloader_uf2.bin
; otherwise,bootloader_uf2.bin
cannot be flashed.Enable the
CONFIG_ENABLE_BOOTLOADER_UF2
macro.Enable the
CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED
macro: Since the position for bootloader_uf2.bin is not explicitly shown in the partition table, the checks must be disabled.Flash the Bin files to the firmware according to the following addresses:
CONFIG_BOOTLOADER_OFFSET_IN_FLASH(The starting addresses vary for different chips.) - bootloader.bin
0x10000 - bootloader_uf2.bin
CONFIG_PARTITION_TABLE_OFFSET (0x6000) - partition-table.bin
Add the following snippet to your project’s CMakeLists.txt to automatically generate a merged Bin file after compilation:
add_custom_command(
TARGET app
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Flash merged bin merge_uf2.bin to address ${CONFIG_BOOTLOADER_OFFSET_IN_FLASH}"
COMMAND ${ESPTOOLPY} --chip ${IDF_TARGET} merge_bin -o merge_uf2.bin ${CONFIG_BOOTLOADER_OFFSET_IN_FLASH} ${BUILD_DIR}/bootloader/bootloader.bin 0x10000 ${BUILD_DIR}/${PROJECT_BIN} ${CONFIG_PARTITION_TABLE_OFFSET} ${BUILD_DIR}/partition_table/partition-table.bin
)
API Reference
Header File
Functions
-
esp_err_t esp_tinyuf2_install(tinyuf2_ota_config_t *ota_config, tinyuf2_nvs_config_t *nvs_config)
Flashing app to specified partition through USB UF2 (Virtual USB Disk), and support operate NVS partition through USB UF2 CONFIG.ini file.
- Parameters
ota_config – tinyuf2 configs described in tinyuf2_ota_config_t
nvs_config – tinyuf2 nvs configs described in tinyuf2_nvs_config_t
- Returns
ESP_ERR_INVALID_ARG invalid parameter, please check partitions
ESP_ERR_INVALID_STATE tinyuf2 already installed
ESP_OK Success
-
esp_err_t esp_tinyuf2_uninstall(void)
Uninstall tinyuf2, only reset USB to default state.
Note
not release memory due to tinyusb not support teardown
- Returns
esp_err_t
ESP_ERR_INVALID_STATE tinyuf2 not installed
ESP_OK Success
-
tinyuf2_state_t esp_tinyuf2_current_state(void)
Get tinyuf2 current state.
- Returns
tinyuf2_state_t
-
void esp_restart_from_tinyuf2(void)
Restart system and set reset reason to UF2_RESET_REASON_VALUE.
Structures
-
struct tinyuf2_ota_config_t
tinyuf2 configurations
Public Members
-
esp_partition_subtype_t subtype
Partition subtype. if ESP_PARTITION_SUBTYPE_ANY will use the next_update_partition by default.
-
const char *label
Partition label. Set this value if looking for partition with a specific name. if subtype==ESP_PARTITION_SUBTYPE_ANY, label default to NULL.
-
bool if_restart
if restart system to new app partition after UF2 flashing done
-
update_complete_cb_t complete_cb
user callback called after uf2 update complete
-
esp_partition_subtype_t subtype
-
struct tinyuf2_nvs_config_t
tinyuf2 nvs configurations
Public Members
-
const char *part_name
Partition name.
-
const char *namespace_name
Namespace name.
-
nvs_modified_cb_t modified_cb
user callback called after uf2 update complete
-
const char *part_name
Macros
-
DEFAULT_TINYUF2_OTA_CONFIG()
-
DEFAULT_TINYUF2_NVS_CONFIG()
-
UF2_RESET_REASON_VALUE
Type Definitions
-
typedef void (*update_complete_cb_t)(void)
user callback called after uf2 update complete
-
typedef void (*nvs_modified_cb_t)(void)
user callback called after nvs modified