@@ -202,262 +202,7 @@ Factory image generated: /Users/mat/Data/Workspace/me/MycilaSafeBoot/examples/Ap
202
202
203
203
the ` factory.py ` script generates a complete factory image named ` firmware.factory.bin ` with all this content.
204
204
205
- Flash this factory image on an ESP32:
206
-
207
- ``` bash
208
- esptool.py write_flash 0x0 .pio/build/esp32dev/firmware.factory.bin
209
- ```
210
-
211
- Restart the ESP.
212
- The app loads, shows a button to restart in SafeBoot mode.
213
- After clicking on it, the ESP will reboot into SafeBoot mode.
214
- From there, you can access the web page to flash a new firmware, even from another application.
215
-
216
- ## How to reboot in SafeBoot mode from the app
217
-
218
- You can use [ MycilaSystem] ( https://github.com/mathieucarbou/MycilaSystem ) :
219
-
220
- ``` cpp
221
- #include < MycilaSystem.h>
222
-
223
- espConnect.saveConfiguration(); // if you want to save ESPConnect settings for network
224
- Mycila::System::restartFactory ("safeboot");
225
- ```
226
-
227
- or this custom code:
228
-
229
- ```cpp
230
- #include <esp_ota_ops.h>
231
- #include <esp_partition.h>
232
-
233
- const esp_partition_t* partition = esp_partition_find_first(esp_partition_type_t::ESP_PARTITION_TYPE_APP, esp_partition_subtype_t::ESP_PARTITION_SUBTYPE_APP_FACTORY, partitionName);
234
- if (partition) {
235
- esp_ota_set_boot_partition(partition);
236
- esp_restart();
237
- return true;
238
- } else {
239
- ESP_LOGE("SafeBoot", "SafeBoot partition not found");
240
- return false;
241
- }
242
- ```
243
-
244
- ## Configuration options to manage build size
245
-
246
- Squezing everything into the SafeBoot partition (655360 bytes only) is a tight fit especially on ethernet enabled boards.
247
-
248
- Disabling the logging capabilites saves about 12 kbytes in the final build. Just comment out ` MYCILA_SAFEBOOT_LOGGING ` in ` platformio.ini ` .
249
-
250
- ``` ini
251
- ; -D MYCILA_SAFEBOOT_LOGGING
252
- ```
253
-
254
- Disabling mDNS saves about 24 kbytes. Enable both [ ...] \_ NO_DNS options in ` platformio.ini ` to reduce the build size:
255
-
256
- ``` ini
257
- -D ESPCONNECT_NO_MDNS
258
- -D MYCILA_SAFEBOOT_NO_MDNS# MycilaSafeBoot
259
-
260
- [![Latest Release] (https://img.shields.io/github/release/mathieucarbou/MycilaSafeBoot.svg)](https://GitHub.com/mathieucarbou/MycilaSafeBoot/releases/)
261
- [![Download] (https://img.shields.io/badge/Download-safeboot-green.svg)](https://github.com/mathieucarbou/MycilaSafeBoot/releases)
262
-
263
- [![License: MIT] (https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
264
- [![Contributor Covenant] (https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md)
265
-
266
- [![Build] (https://github.com/mathieucarbou/MycilaSafeBoot/actions/workflows/build.yml/badge.svg)](https://github.com/mathieucarbou/MycilaSafeBoot/actions/workflows/build.yml)
267
- [![GitHub latest commit] (https://badgen.net/github/last-commit/mathieucarbou/MycilaSafeBoot)](https://GitHub.com/mathieucarbou/MycilaSafeBoot/commit/)
268
- [![Gitpod Ready-to-Code] (https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo =gitpod)](https://gitpod.io/# https://github.com/mathieucarbou/MycilaSafeBoot)
269
-
270
- MycilaSafeBoot is a Web OTA recovery partition for ESP32 / Arduino.
271
-
272
- It allows to have only one application partition to use the maximum available flash size.
273
-
274
- The idea is not new: [Tasmota also uses a SafeBoot partition](https://tasmota.github.io/docs/Safeboot/).
275
-
276
- - [Overview](# overview)
277
- - [How it works](# how-it-works)
278
- - [How to integrate the SafeBoot in your project](# how-to-integrate-the-safeboot-in-your-project)
279
- - [How to build the SafeBoot firmware image](# how-to-build-the-safeboot-firmware-image)
280
- - [SafeBoot Example](# safeboot-example)
281
- - [How to reboot in SafeBoot mode from the app](# how-to-reboot-in-safeboot-mode-from-the-app)
282
- - [Configuration options to manage build size](# configuration-options-to-manage-build-size)
283
- - [Options matrix](# options-matrix)
284
- - [Default board options](# default-board-options)
285
-
286
- [![] (https://mathieu.carbou.me/MycilaSafeBoot/safeboot-ssid.jpeg)](https://mathieu.carbou.me/MycilaSafeBoot/safeboot-ssid.jpeg)
287
-
288
- # # Overview
289
-
290
- Usually, a normal partition table when supporting OTA updates on a 4MB ESP32 looks like this:
291
-
292
- ```
293
- # Name, Type, SubType, Offset, Size, Flags
294
- nvs, data, nvs, 0x9000, 0x5000,
295
- otadata, data, ota, 0xE000, 0x2000,
296
- app0, app, ota_0, 0x10000, 0x1F0000,
297
- app1, app, ota_1, 0x200000, 0x1F0000,
298
- spiffs, data, spiffs, 0x3F0000, 0x10000,
299
- ```
300
-
301
- which can also be written as:
302
-
303
- ```
304
- # Name ,Type ,SubType ,Offset ,Size ,Flags
305
- nvs ,data ,nvs ,36K ,20K ,
306
- otadata ,data ,ota ,56K ,8K ,
307
- app0 ,app ,ota_0 ,64K ,1984K ,
308
- app1 ,app ,ota_1 ,2048K ,1984K ,
309
- spiffs ,data ,spiffs ,4032K ,64K ,
310
- ```
311
-
312
- Because of the need to have 2 partitions with the same size, the firmware is then limited to only 2MB in this case when the ESP has 4MB flash.
313
- 2MB is left unused (the OTA process will switch to the updated partition once completed).
314
-
315
- **A SafeBoot partition is a small bootable recovery partition allowing you to flash the firmware.**
316
- Consequently, the firmware can take all the remaining space on the flash.
317
-
318
- **The SafeBoot partition is 655360 bytes only.**
319
-
320
- **Example for 4MB partition** with a SafeBoot partition and an application size of 3MB:
321
-
322
- ```
323
- # Name, Type, SubType, Offset, Size, Flags
324
- nvs, data, nvs, 0x9000, 0x5000,
325
- otadata, data, ota, 0xE000, 0x2000,
326
- safeboot, app, factory, 0x10000, 0xA0000,
327
- app, app, ota_0, 0xB0000, 0x330000,
328
- spiffs, data, spiffs, 0x3E0000, 0x10000,
329
- coredump, data, coredump, 0x3F0000, 0x10000,
330
- ```
331
-
332
- which can also be written as:
333
-
334
- ```
335
- # Name ,Type ,SubType ,Offset ,Size ,Flags
336
- nvs ,data ,nvs ,36K ,20K ,
337
- otadata ,data ,ota ,56K ,8K ,
338
- safeboot ,app ,factory ,64K ,640K ,
339
- app ,app ,ota_0 ,704K ,3264K ,
340
- spiffs ,data ,spiffs ,3968K ,64K ,
341
- coredump ,data ,coredump ,4032K ,64K ,
342
- ```
343
-
344
- **Example for 8Mb partition** with a SafeBoot partition and an application size of 7MB:
345
-
346
- ```
347
- # Name, Type, SubType, Offset, Size, Flags
348
- nvs, data, nvs, 0x9000, 0x5000,
349
- otadata, data, ota, 0xE000, 0x2000,
350
- safeboot, app, factory, 0x10000, 0xA0000,
351
- app, app, ota_0, 0xB0000, 0x730000,
352
- spiffs data, spiffs, 0x7E0000, 0x10000,
353
- coredump, data, coredump, 0x7F0000, 0x10000,
354
- ```
355
-
356
- which can also be written as:
357
-
358
- ```
359
- # Name ,Type ,SubType ,Offset ,Size ,Flags
360
- nvs ,data ,nvs ,36K ,20K ,
361
- otadata ,data ,ota ,56K ,8K ,
362
- safeboot ,app ,factory ,64K ,640K ,
363
- app ,app ,ota_0 ,704K ,7312K ,
364
- spiffs ,data ,spiffs ,8128K ,64K ,
365
- coredump ,data ,coredump ,8192K ,64K ,
366
- ```
367
-
368
- The SafeBoot partition is also automatically booted when the firmware is missing.
369
-
370
- ## How it works
371
-
372
- 1. When a user wants to update the app firmware, we have to tell the app to reboot in recovery mode.
373
-
374
- 2. Once booted in recovery mode, an Access Point is created with the SSID `SafeBoot`.
375
-
376
- [](https://mathieu.carbou.me/MycilaSafeBoot/safeboot-ssid.jpeg)
377
-
378
- 3. Connect to the Access Point.
379
-
380
- 4. Now, you can flash the new firmware, either with `ArduinoOTA` or from the web page by going to `http://192.168.4.1`
381
-
382
- 5. After the flash is successful, the ESP will reboot in the new firmware.
383
-
384
- SafeBoot partition also supports [MycilaESPConnect](https://github.com/mathieucarbou/MycilaESPConnect), which means if your application saves some network settings (WiFi SSID, Ethernet or WiFi static IP, etc), they will be reused.
385
-
386
- ## How to integrate the SafeBoot in your project
387
-
388
- In the PIO file, some settings are added to specify the partition table and the SafeBoot location and the script to generate the factory image.
389
-
390
- ```ini
391
- extra_scripts = post:factory.py
392
- board_build.partitions = partitions-4MB-safeboot.csv
393
- board_build.app_partition_name = app
394
- custom_safeboot_url = https://github.com/mathieucarbou/MycilaSafeBoot/releases/download/latest/safeboot-esp32dev.bin
395
- ```
396
-
397
- It is also possible to point to a folder if you download the SafeBoot project locally:
398
-
399
- ``` ini
400
- custom_safeboot_dir = ../../tools/SafeBoot
401
- ```
402
-
403
- It is also possible to point to a pre-downloaded safeoot image:
404
-
405
- ``` ini
406
- custom_safeboot_file = safeboot.bin
407
- ```
408
-
409
- You can find in the [ Project Releases] ( https://github.com/mathieucarbou/MycilaSafeBoot/releases ) the list of available SafeBoot images, with the Python script to add to your build.
410
-
411
- ## How to build the SafeBoot firmware image
412
-
413
- Go inside ` tools/SafeBoot ` and run:
414
-
415
- ``` bash
416
- > pio run -e esp32dev
417
- ```
418
-
419
- If your board does not exist, you can specify it like this:
420
-
421
- ``` bash
422
- > SAFEBOOT_BOARD=my-board pio run -e safeboot
423
- ```
424
-
425
- ` SAFEBOOT_BOARD ` is the environment variable to specify the board to build the SafeBoot firmware for.
426
-
427
- At the end you should see these lines:
428
-
429
- ```
430
- Firmware size valid: 619744 <= 655360
431
- SafeBoot firmware created: /Users/mat/Data/Workspace/me/MycilaSafeBoot/.pio/build/dev/safeboot.bin
432
- ```
433
-
434
- ## SafeBoot Example
435
-
436
- Go inside ` examples/App ` and execute:
437
-
438
- ``` bash
439
- > pio run
440
- ```
441
-
442
- You should see at the end of the build something like:
443
-
444
- ```
445
- Generating factory image for serial flashing
446
- Downloading SafeBoot image from https://github.com/mathieucarbou/MycilaSafeBoot/releases/download/latest/safeboot-esp32dev.bin
447
- Offset | File
448
- - 0x1000 | /Users/mat/Data/Workspace/me/MycilaSafeBoot/examples/App/.pio/build/esp32dev/bootloader.bin
449
- - 0x8000 | /Users/mat/Data/Workspace/me/MycilaSafeBoot/examples/App/.pio/build/esp32dev/partitions.bin
450
- - 0xe000 | /Users/mat/.platformio/packages/framework-arduinoespressif32@src-17df1753722b7b9e1913598420d4e038/tools/partitions/boot_app0.bin
451
- - 0x10000 | /Users/mat/Data/Workspace/me/MycilaSafeBoot/examples/App/.pio/build/esp32dev/safeboot.bin
452
- - 0xb0000 | /Users/mat/Data/Workspace/me/MycilaSafeBoot/examples/App/.pio/build/esp32dev/firmware.bin
453
-
454
- [...]
455
-
456
- Wrote 0x1451a0 bytes to file /Users/mat/Data/Workspace/me/MycilaSafeBoot/examples/App/.pio/build/esp32dev/firmware.factory.bin, ready to flash to offset 0x0
457
- Factory image generated: /Users/mat/Data/Workspace/me/MycilaSafeBoot/examples/App/.pio/build/esp32dev/firmware.factory.bin
458
- ```
459
-
460
- the ` factory.py ` script generates a complete factory image named ` firmware.factory.bin ` with all this content.
205
+ It can be downloaded from [ https://github.com/mathieucarbou/MycilaSafeBoot/releases ] ( https://github.com/mathieucarbou/MycilaSafeBoot/releases ) .
461
206
462
207
Flash this factory image on an ESP32:
463
208
@@ -559,48 +304,25 @@ Disabling mDNS saves about 24 kbytes. Enable both [...]\_NO_DNS options in `plat
559
304
| wipy3 | ✅ | ❌ | ❌ |
560
305
| wt32-eth01 | ❌ | ❌ | ✅ |
561
306
562
- ```
307
+ ## How to automatically update a firmware from PlatformIO
563
308
564
- ### Options matrix
309
+ First make sure you created an HTTP endpoint that can be called to restart the app in SafeBoot mode.
310
+ See [ How to reboot in SafeBoot mode from the app] ( #how-to-reboot-in-safeboot-mode-from-the-app ) .
565
311
566
- | Board | mDNS: on, logger: on | mDNS: on, logger: off | mDNS: off, logger: off |
567
- | -------------------- | -------------------- | --------------------- | ---------------------- |
568
- | denky_d4 | NOT SUPPORTED | OK | OK |
569
- | esp32-c3-devkitc-02 | OK | OK | OK |
570
- | esp32-c6-devkitc-1 | NOT SUPPORTED | NOT SUPPORTED | OK |
571
- | esp32-gateway | NOT SUPPORTED | OK | OK |
572
- | esp32-poe | NOT SUPPORTED | NOT SUPPORTED | OK |
573
- | esp32-poe-iso | NOT SUPPORTED | NOT SUPPORTED | OK |
574
- | esp32-s2-saola-1 | OK | OK | OK |
575
- | esp32-s3-devkitc-1 | OK | OK | OK |
576
- | esp32-solo1 | OK | OK | OK |
577
- | esp32dev | OK | OK | OK |
578
- | esp32s3box | OK | OK | OK |
579
- | lilygo-t-eth-lite-s3 | OK | OK | OK |
580
- | lolin_s2_mini | OK | OK | OK |
581
- | tinypico | NOT SUPPORTED | OK | OK |
582
- | wemos_d1_uno32 | OK | OK | OK |
583
- | wipy3 | NOT SUPPORTED | OK | OK |
584
- | wt32-eth01 | NOT SUPPORTED | NOT SUPPORTED | OK |
312
+ Then add to your PlatformIO ` platformio.ini ` file:
585
313
586
- ## Default board options
314
+ ``` ini
315
+ upload_protocol = espota
316
+ upload_port = 192.168.125.99
317
+ custom_safeboot_restart_path = /api/system/safeboot
318
+ extra_scripts =
319
+ tools/safeboot.py
320
+ ```
321
+
322
+ The ` safeboot.py ` script can be downloaded from teh release page: [ https://github.com/mathieucarbou/MycilaSafeBoot/releases ] ( https://github.com/mathieucarbou/MycilaSafeBoot/releases ) .
323
+
324
+ - ` upload_protocol = espota ` tells PlatformIO to use Arduono OTA to upload the firmware
325
+ - ` upload_port ` is the IP address of the ESP32
326
+ - ` custom_safeboot_restart_path ` is the path to call to restart the app in SafeBoot mode
587
327
588
- | Board | mDNS | Logging |
589
- | :------------------- | :--: | :-----: |
590
- | denky_d4 | ✅ | ❌ |
591
- | esp32-c3-devkitc-02 | ✅ | ✅ |
592
- | esp32-c6-devkitc-1 | ❌ | ❌ |
593
- | esp32-gateway | ✅ | ❌ |
594
- | esp32-poe | ❌ | ❌ |
595
- | esp32-poe-iso | ❌ | ❌ |
596
- | esp32-s2-saola-1 | ✅ | ✅ |
597
- | esp32-s3-devkitc-1 | ✅ | ✅ |
598
- | esp32-solo1 | ✅ | ✅ |
599
- | esp32dev | ✅ | ✅ |
600
- | esp32s3box | ✅ | ✅ |
601
- | lilygo-t-eth-lite-s3 | ✅ | ✅ |
602
- | lolin_s2_mini | ✅ | ✅ |
603
- | tinypico | ✅ | ❌ |
604
- | wemos_d1_uno32 | ✅ | ✅ |
605
- | wipy3 | ✅ | ❌ |
606
- | wt32-eth01 | ❌ | ❌ |
328
+ Once done, just run a ` pio run -t upload ` or ` pio run -t uploadfs ` for example and you will see the app automatically restarting in SafeBoot mode, then upload will be achieved, then the ESP will be restarted with your new app.
0 commit comments