## ESP TinyUF2 The enhanced version of [TinyUF2](https://github.com/adafruit/tinyuf2) for ESP32Sx, which supports over-the-air (OTA) updates for APP. **and supports dumping NVS key-value pairs to the config file, users can modify and write back to NVS**. UF2 is a file format developed by Microsoft for [PXT](https://github.com/Microsoft/pxt), that is particularly suitable for flashing microcontrollers over MSC (Mass Storage Class). For a more friendly explanation, check out [this blog post](https://makecode.com/blog/one-chip-to-flash-them-all). ## Support UF2 OTA/NVS in Your Project 1. Add the component to your project using `idf.py add_dependency` command. ```sh idf.py add-dependency "esp_tinyuf2" ``` 2. Customer your partition table. Like other OTA solutions, you need to reserve at least two OTA app partitions. Please refer to [Partition Tables](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html) and [usb_uf2_ota](../../../examples/usb/device/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, ``` 3. 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 default * `Max APP size(MB)`: Maximum APP size, 4MB by default * `Flash cache size(KB)`: Cache size used for writing Flash efficiently, 32KB by default * `USB Device VID`: Espressif VID (0x303A) by default * `USB Device PID`: Espressif test PID (0x8000) by default, refer [esp-usb-pid](https://github.com/espressif/usb-pids) to apply new. * `USB Disk Name`: The name of the virtual U-disk shows in File Explorer, "ESP32Sx-UF2" by default * `USB Device Manufacture`: "Espressif" by default * `Product Name`: "ESP TinyUF2" by default * `Product ID`: 12345678 by default * `Product URL`: A `index` file will be added to the U-disk, users can click to goto the webpage, "https://products.espressif.com/" by default * `UF2 NVS ini file size`: The `ini` file size prepares for NVS function 4. Install tinyuf2 function like below, for more details, please refer example `usb_uf2_nvs` and `usb_uf2_ota` ```c /* 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); ``` 5. Run `idf.py build flash` for the initial download, later `idf.py uf2-ota` can be used to generate new `uf2` app bin 6. Drag and drop UF2 format file to the disk, to upgrade to new `uf2` app bin ![UF2 Disk](./uf2_disk.png) ## Enable UF2 USB Console If enable UF2 USB console `(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. ```sh idf.py uf2-ota ``` ## Convert Existing APP to UF2 Format To convert your existing APP binary to UF2 format, simply use the [uf2conv.py](./utils/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. 1. convert as follows using: ```sh $ENV{UF2_UTILS_PATH}/uf2conv.py your_firmware.bin -c -b 0x00 -f ESP32S3 ``` or: ```sh $ENV{UF2_UTILS_PATH}/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.
# ChangeLog ## v0.2.1 - 2024-04-22 * Fix build with latest ESP-IDF (USB Hal: Change name of usb_phy HAL files to usb_fsls_phy) ## v0.2.0 - 2023-07-17 * Support `esp_tinyuf2_uninstall` API (Restore the USB hardware to default state, Not teardown TinyUSB stack) * Support target test ## v0.1.0 - 2023-07-05 * Support USB Console for log (disabled by default) ## v0.0.2 - 2023-07-03 * Add Linux INI file write workaround ## v0.0.1 - 2023-06-26 * initial version * Support update APP through UF2 * Support modify NVS through UF2
## TinyUF2 NVS Example The TinyUF2 supports dumping NVS key-value pairs to the config file, i.e., users can access and modify the NVS data and subsequently write the updated values back to the NVS. This example demonstrates a new Wi-Fi Provisioning solution through TinyUF2. ## How to use the example ## Build and Flash Run `idf.py -p PORT flash monitor` to build and flash the project. (To exit the serial monitor, type Ctrl-].) See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. ## Provisioning through Modify `INI` file * Build and flash the firmware. * Insert `ESP32S3` to PC through USB, New disk name with `ESP32S2-UF2` will be found in File Manager. * Open the `CONFIG.INI`, edit `ssid` and `password` then save. * The saved file will be parsed by ESP32S3, then write the key-value pairs to NVS. * The new `ssid` and `password` will be used for Wi-Fi connect. ![UF2 Disk](../../../../components/usb/esp_tinyuf2/uf2_disk.png) ## Example Output ``` I (0) cpu_start: Starting scheduler on APP CPU. I (448) uf2_nvs_example: no ssid, give a init value to nvs I (448) uf2_nvs_example: no password, give a init value to nvs I (448) TUF2: UF2 Updater install succeed, Version: 0.0.1 I (778) tud_mount_cb: I (27608) uf2_nvs_example: uf2 nvs modified .... I (32888) uf2_nvs_example: wifi start ssid:ESP password:espressif I (32908) wifi:new:<1,1>, old:<1,0>, ap:<255,255>, sta:<1,1>, prof:1 I (33948) wifi:state: init -> auth (b0) I (33958) wifi:state: auth -> assoc (0) I (33978) wifi:state: assoc -> run (10) I (34098) wifi:connected with ESP, aid = 1, channel 1, 40U, bssid = bc:5f:f6:1b:28:5e I (34098) wifi:security: WPA2-PSK, phy: bgn, rssi: -26 I (34108) wifi:pm start, type: 1 I (34108) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 0, mt_pti: 25000, mt_time: 10000 I (34108) wifi:AP's beacon interval = 102400 us, DTIM period = 1 I (34128) wifi:<ba-add>idx:0 (ifx:0, bc:5f:f6:1b:28:5e), tid:0, ssn:3, winSize:64 I (35618) esp_netif_handlers: sta ip: 192.168.1.9, mask: 255.255.255.0, gw: 192.168.1.1 I (35618) uf2_nvs_example: got ip:192.168.1.9 ```
## TinyUF2 OTA Example UF2 is a file format developed by Microsoft for [PXT](https://github.com/Microsoft/pxt), that is particularly suitable for flashing microcontrollers over MSC (Mass Storage Class). For a more friendly explanation, check out [this blog post](https://makecode.com/blog/one-chip-to-flash-them-all). ## How to use the example ## Build and Flash Run `idf.py -p PORT flash monitor` to build and flash the project. (To exit the serial monitor, type Ctrl-].) See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. ## Drag and drop to upgrade * Build and flash the first TinyUF2 supported firmware * Insert `ESP32S3` to PC through USB, New disk name with `ESP32S2-UF2` will be found in File Manager * Run `idf.py uf2-ota` to generate or convert subsequent firmware upgrades to UF2 format, refer [esp_tinyuf2](../../../../components/usb/esp_tinyuf2/) for more details * Drag and drop UF2 format firmware to the disk to upgrade ![UF2 Disk](../../../../components/usb/esp_tinyuf2/uf2_disk.png) ## Example Output ``` I (8456) esp_image: segment 0: paddr=00010020 vaddr=3f000020 size=0857ch ( 34172) map I (8466) esp_image: segment 1: paddr=000185a4 vaddr=3ffbd8c0 size=01d98h ( 7576) I (8466) esp_image: segment 2: paddr=0001a344 vaddr=40022000 size=05cd4h ( 23764) I (8476) esp_image: segment 3: paddr=00020020 vaddr=40080020 size=18248h ( 98888) map I (8496) esp_image: segment 4: paddr=00038270 vaddr=40027cd4 size=05be4h ( 23524) I (8506) esp_image: segment 5: paddr=0003de5c vaddr=50000000 size=00010h ( 16) I (8556) uf2_example: Firmware update complete I (8556) uf2_example: Restarting in 5 seconds... I (9556) uf2_example: Restarting in 4 seconds... I (10556) uf2_example: Restarting in 3 seconds... I (11556) uf2_example: Restarting in 2 seconds... I (12556) uf2_example: Restarting in 1 seconds... I (13556) uf2_example: Restarting in 0 seconds... I (14556) uf2_example: Restarting now ```
d014b23f2bab119c0e41c2b9365a13e21bb8b503
idf.py add-dependency "espressif/esp_tinyuf2^0.2.1"
To create a project from this example, run:
idf.py create-project-from-example "espressif/esp_tinyuf2^0.2.1:usb_uf2_nvs"
To create a project from this example, run:
idf.py create-project-from-example "espressif/esp_tinyuf2^0.2.1:usb_uf2_ota"