{"id":16240021,"url":"https://github.com/georgik/esp32-graphical-bootloader","last_synced_at":"2025-03-19T16:31:43.037Z","repository":{"id":228804935,"uuid":"774949781","full_name":"georgik/esp32-graphical-bootloader","owner":"georgik","description":"ESP32 Application which acts as 3rd stage bootloader and allows switching applications stored in OTA partitions","archived":false,"fork":false,"pushed_at":"2024-08-19T11:10:58.000Z","size":167,"stargazers_count":22,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-17T09:06:46.510Z","etag":null,"topics":["bootloader","esp-idf","esp32p4","esp32s3-box","m5stack-cores3"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/georgik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-20T13:50:28.000Z","updated_at":"2025-03-12T10:51:09.000Z","dependencies_parsed_at":"2024-10-27T21:23:46.433Z","dependency_job_id":"ad79e82d-edec-49ea-aa8f-66b5c6fff772","html_url":"https://github.com/georgik/esp32-graphical-bootloader","commit_stats":null,"previous_names":["georgik/esp32-graphical-bootloader"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/georgik%2Fesp32-graphical-bootloader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/georgik%2Fesp32-graphical-bootloader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/georgik%2Fesp32-graphical-bootloader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/georgik%2Fesp32-graphical-bootloader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/georgik","download_url":"https://codeload.github.com/georgik/esp32-graphical-bootloader/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244463823,"owners_count":20456944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bootloader","esp-idf","esp32p4","esp32s3-box","m5stack-cores3"],"created_at":"2024-10-10T13:45:56.034Z","updated_at":"2025-03-19T16:31:42.529Z","avatar_url":"https://github.com/georgik.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ESP32 Graphical Bootloader\n\n3rd stage graphical bootloader which lets you pick applications stored in OTA partitions.\n\n\n## How it works\n\nThe bootloader allows user to select an application from graphical menu. After the selection the partition is selected and the chip rebooted. The bootloader switches to the newly selected application. During the start of the application there is a code which switches bootloader back to the first application with the bootloader. After another restart the original application with the bootloader is visible again.\n\n### Test on-line\n\n[![ESP32-S3-Box-3 Graphical Bootloader](doc/esp32-s3-box-3-graphical-bootloader.webp)](https://wokwi.com/experimental/viewer?diagram=https://gist.githubusercontent.com/urish/c3d58ddaa0817465605ecad5dc171396/raw/ab1abfa902835a9503d412d55a97ee2b7e0a6b96/diagram.json\u0026firmware=https://github.com/georgik/esp32-graphical-bootloader/releases/latest/download/graphical-bootloader-esp32-s3-box.uf2\n)\n\n[Run on-line in Wokwi Simulator](https://wokwi.com/experimental/viewer?diagram=https://gist.githubusercontent.com/urish/c3d58ddaa0817465605ecad5dc171396/raw/ab1abfa902835a9503d412d55a97ee2b7e0a6b96/diagram.json\u0026firmware=https://github.com/georgik/esp32-graphical-bootloader/releases/latest/download/graphical-bootloader-esp32-s3-box.uf2)\n\n## Selected board\n\nThe project is by default configured for ESP32-S3-BOX-3. Build configuration for the available boards are stored in `boards` directory.\nIf you need a different board please run one of following exports and then CMake command:\n\n- ESP32-S3-BOX-3\n```shell\nidf.py @boards/esp-box-3.cfg reconfigure\n```\n\n- ESP32-S3-BOX (prior Dec. 2023)\n```shell\nidf.py @boards/esp-box.cfg reconfigure\n```\n\n- ESP32-P4\n```shell\nidf.py @boards/esp32_p4_function_ev_board.cfg reconfigure\n```\n\n- M5Stack-CoreS3\n```shell\nidf.py @boards/m5stack_core_s3.cfg reconfigure\n```\n\n## Quick start\n\nBuild and flash all applications at once:\n\n```shell\ncmake -DBUILD_BOARD=esp-box-3 -Daction=build_all_apps -P Bootloader.cmake\n```\n\n## Build applications one by one\n\nApplications are stored in ota_0 - ota_4 with the following offset:\n- ota_0 - 0x220000\n- ota_1 - 0x4E0000\n- ota_2 - 0x7A0000\n- ota_3 - 0xA60000\n- ota_4 - 0xD20000\n\nCommands to build and flash appplications:\n```shell\nidf.py @boards/esp-box-3.cfg build\npushd apps/tic_tac_toe\nidf.py @../../boards/esp-box-3.cfg build\nesptool.py --before default_reset --after hard_reset write_flash 0x220000 build.esp-box-3/tic_tac_toe.bin\npopd\npushd apps/wifi_list\nidf.py @../../boards/esp-box-3.cfg build\nesptool.py --before default_reset --after hard_reset write_flash 0x4E0000 build.esp-box-3/wifi_list.bin\npopd\npushd apps/calculator\nidf.py @../../boards/esp-box-3.cfg build\nesptool.py --before default_reset --after hard_reset write_flash 0x7A0000 build.esp-box-3/calculator.bin\npopd\npushd apps/synth_piano\nidf.py @../../boards/esp-box-3.cfg build\nesptool.py --before default_reset --after hard_reset write_flash 0xA60000 build.esp-box-3/synth_piano.bin\npopd\npushd apps/game_of_life\nidf.py @../../boards/esp-box-3.cfg build\nesptool.py --before default_reset --after hard_reset write_flash 0xD20000 build.esp-box-3/game_of_life.bin\npopd\n```\n\nAlternatively you can use [espflash](https://github.com/esp-rs/espflash/blob/main/espflash/README.md#installation):\n```\nespflash write-bin 0xD20000 .\\build.esp-box-3\\app.bin\n```\n\n### Merging all applications\n\nThe following command merges all applications into binary image format:\n```shell\nesptool.py --chip esp32s3 merge_bin  -o build.esp-box-3/combined.bin --flash_mode dio --flash_size 16MB \\\n    0x0 build.esp-box-3/bootloader/bootloader.bin \\\n    0x8000 build.esp-box-3/partition_table/partition-table.bin \\\n    0xf000 build.esp-box-3/ota_data_initial.bin \\\n    0x20000 build.esp-box-3/esp32-graphical-bootloader.bin \\\n    0x220000 apps/tic_tac_toe/build.esp-box-3/tic_tac_toe.bin \\\n    0x4E0000 apps/wifi_list/build.esp-box-3/wifi_list.bin \\\n    0x7A0000 apps/calculator/build.esp-box-3/calculator.bin \\\n    0xA60000 apps/synth_piano/build.esp-box-3/synth_piano.bin \\\n    0xD20000 apps/game_of_life/build.esp-box-3/game_of_life.bin\n```\n\nThe single binary can be flashed by command:\n\n```shell\nesptool.py --chip esp32s3  --baud 921600 write_flash 0x0000 build.esp-box-3/combined.bin\n```\n\n## Create custom app\n\nYou can use ESP-IDF app, just you need to make sure that application has fallback mechanism to factory app. This can be achieving by following code.\n\n## Updating apps to fallback to bootloader\n\nThe bootloader is using OTA mechanism. It's necessary to add following code to the application\nin order to reboot to bootloader.\n\nPut the following code to main, before starting the rest of the application:\n```c\n#include \"esp_ota_ops.h\"\n\nconst esp_partition_t* factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);\nif (factory_partition != NULL) {\n    esp_ota_set_boot_partition(factory_partition);\n}\n```\n\nMore elaborate version which can be put somwhere into application, like reaction on back button:\n\n```c\n#include \"esp_ota_ops.h\"\n\n// Get the partition structure for the factory partition\nconst esp_partition_t *factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);\nif (factory_partition != NULL) {\n    if (esp_ota_set_boot_partition(factory_partition) == ESP_OK) {\n        printf(\"Set boot partition to factory.\\n\");\n    } else {\n        printf(\"Failed to set boot partition to factory.\\n\");\n    }\n} else {\n    printf(\"Factory partition not found.\\n\");\n}\n\nfflush(stdout);\nprintf(\"Restarting now.\\n\");\nesp_restart();\n```\n\nIf the project is using explicit list of components, you need to add `app_update` into `main/CMakeLists.txt`, so it looks like this:\n```\nidf_component_register(\n    SRCS \"main.cpp\"\n    INCLUDE_DIRS \".\"\n    REQUIRES app_update\n)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeorgik%2Fesp32-graphical-bootloader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeorgik%2Fesp32-graphical-bootloader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeorgik%2Fesp32-graphical-bootloader/lists"}