Page 1 of 1

FOTA help

Posted: Mon Sep 25, 2017 12:54 pm
by remeshck
I am using ESP32 :
Now I am able to publish and subscribe to AWS .
My next task is update the firmware using AWS.
Requirement :
1. Keep the .bin file to AWS S3 bucket
2. Run the ESP32 IOT application on the ESP32 module
3. If there is a version mismatch ,download the firmware from the AWS S3 bucket and load that file to ESP32
Is this possible ?
If possible please provide me link for this implementation

Re: FOTA help

Posted: Sat Oct 07, 2017 5:46 pm
by sukeshak

Re: FOTA help

Posted: Wed Oct 11, 2017 12:14 pm
by remeshck
ota is working for me.
now i want to keep the .bin file AWS S3 bucket and try the same .
what are the changes required to implement for this

Re: FOTA help

Posted: Fri Dec 08, 2017 5:55 pm
by Ritesh
Hi Loboris, Kolban, Espressif Systems Developer

Just want to confirm that this FOTA example will work into OTA0 and OTA1 partition if we create partition table for 2 OTA partition mechanism?

Means there are mainly 3 different partitions for Firmware which will be running.

1) Default OTA partition

2) OTA0 Partition

3) OTA1 Partition

So, we have tried before to use FOTA update for OTA0 and OTA1 partition when we started to work on ESP32 IDF 1.0 SDK but at that time it was not working but then we have used default OTA partition and OTA0 Partition for FOR A update.

So, Now we just want to keep default production firmware to be running I to default partition and want to execute firmware from OTA0 and OTA1 partition based on FOTA update and switching mechanism.

Let me know if you have any idea for that.

Re: FOTA help

Posted: Fri Dec 08, 2017 7:29 pm
by loboris
You can use OTA update with 2 or 3 partition structure.
If using 2 partitions, after each update, the system wil boot from the last updated partition, no factory partition is available.
Both partitions must be of type app and subtype ota_0 & ota_1.

Here is example partition table from my MicroPython port (on 4 MB Falsh):

Code: Select all

# -------------------------------------------------------
# Name,         Type, SubType, Offset,  Size,       Flags
# -------------------------------------------------------
nvs,            data, nvs,     0x9000,  16K,
otadata,        data, ota,     0xd000,  8K,
phy_init,       data, phy,     0xf000,  4K,
MicroPython_1,  app,  ota_0,   0x10000, 1856K,
MicroPython_2,  app,  ota_1,   ,        1856K,
internalfs,     data, fat,     ,        320K,
If using 3 partitions, after each update, the system wil boot from the last updated ota partition.
First partitions subtype is factory and the subtype of the 2nd and 3rd partition is ota_0 & ota_1.
After the first update, the system will never boot from the factory partition (if any of the ota partitions are bootable), unless you change the bootloader (bootloader_start.c) to enable forced boot from factory partition, usually on some gpio level.
You can also select factory partition as boot partition from application software.

Here is example partition table from my MicroPython port (on 8 MB Falsh):

Code: Select all

# -------------------------------------------------------
# Name,         Type, SubType, Offset,  Size,       Flags
# -------------------------------------------------------
nvs,            data, nvs,     0x9000,  16K,
otadata,        data, ota,     0xd000,  8K,
phy_init,       data, phy,     0xf000,  4K,
MicroPython,    app,  factory, 0x10000, 1856K,
MicroPython_1,  app,  ota_0,   ,        1856K,
MicroPython_2,  app,  ota_1,   ,        1856K,
internalfs,     data, fat,     ,        2560K,
Example of modified bootloader_start.c to enable forced boot from factory partition when GPIO02 is low.

Add function to bootloader_start.c:

Code: Select all

static uint8_t ForceFactoryBoot(void)
{
	#if CONFIG_GPIO_INPUT_FORCE_FACTORY
	uint8_t timer = 0;
	gpio_pad_select_gpio(2);
	ets_delay_us(10000); //delay 10 msecs

	while (GPIO_INPUT_GET(2)) {
		if ((timer % 5) == 0) {
			ESP_LOGE(TAG, "Force Factory boot Pin is Active!");
		}
		ets_delay_us(100000); // wait 100 ms
		timer++;
		if (timer == 30) {
			ESP_LOGE(TAG, "Forcing boot to Factory partition");
			return 1;
		}
	}
	ESP_LOGW(TAG, "Normal boot");
	#endif
    return 0;
}
and change the line:

Code: Select all

    if (bs->ota_info.offset != 0) {
to:

Code: Select all

    if (bs->ota_info.offset != 0 && !ForceFactoryBoot()) {

Re: FOTA help

Posted: Fri Dec 08, 2017 7:33 pm
by chegewara
It is possible and its not as hard to implement, but in my opinion it is waste of flash space. Ive been "working" on similar approach lately and what i did is:
- one OTA partition which is used to keep factory firmware. factory firmware is basicaly used to download and flash new firmware to 2nd OTA
-one OTA partition to keep main application which will have minimal interface to check if new application is available and if is then switch to first ota partition which will perform update.

If you wish to have 3 partitions you can make similar implementation:
- one ota partition to keep firmware,
- two ota partitions to have application,
- esp-idf ota example write new application to unused ota partition, you can add option to check if its firmware partition, if it is then find next ota partition and perform ota update

Re: FOTA help

Posted: Sat Dec 09, 2017 4:56 pm
by Ritesh
loboris wrote:You can use OTA update with 2 or 3 partition structure.
If using 2 partitions, after each update, the system wil boot from the last updated partition, no factory partition is available.
Both partitions must be of type app and subtype ota_0 & ota_1.

Here is example partition table from my MicroPython port (on 4 MB Falsh):

Code: Select all

# -------------------------------------------------------
# Name,         Type, SubType, Offset,  Size,       Flags
# -------------------------------------------------------
nvs,            data, nvs,     0x9000,  16K,
otadata,        data, ota,     0xd000,  8K,
phy_init,       data, phy,     0xf000,  4K,
MicroPython_1,  app,  ota_0,   0x10000, 1856K,
MicroPython_2,  app,  ota_1,   ,        1856K,
internalfs,     data, fat,     ,        320K,
If using 3 partitions, after each update, the system wil boot from the last updated ota partition.
First partitions subtype is factory and the subtype of the 2nd and 3rd partition is ota_0 & ota_1.
After the first update, the system will never boot from the factory partition (if any of the ota partitions are bootable), unless you change the bootloader (bootloader_start.c) to enable forced boot from factory partition, usually on some gpio level.
You can also select factory partition as boot partition from application software.

Here is example partition table from my MicroPython port (on 8 MB Falsh):

Code: Select all

# -------------------------------------------------------
# Name,         Type, SubType, Offset,  Size,       Flags
# -------------------------------------------------------
nvs,            data, nvs,     0x9000,  16K,
otadata,        data, ota,     0xd000,  8K,
phy_init,       data, phy,     0xf000,  4K,
MicroPython,    app,  factory, 0x10000, 1856K,
MicroPython_1,  app,  ota_0,   ,        1856K,
MicroPython_2,  app,  ota_1,   ,        1856K,
internalfs,     data, fat,     ,        2560K,
Example of modified bootloader_start.c to enable forced boot from factory partition when GPIO02 is low.

Add function to bootloader_start.c:

Code: Select all

static uint8_t ForceFactoryBoot(void)
{
	#if CONFIG_GPIO_INPUT_FORCE_FACTORY
	uint8_t timer = 0;
	gpio_pad_select_gpio(2);
	ets_delay_us(10000); //delay 10 msecs

	while (GPIO_INPUT_GET(2)) {
		if ((timer % 5) == 0) {
			ESP_LOGE(TAG, "Force Factory boot Pin is Active!");
		}
		ets_delay_us(100000); // wait 100 ms
		timer++;
		if (timer == 30) {
			ESP_LOGE(TAG, "Forcing boot to Factory partition");
			return 1;
		}
	}
	ESP_LOGW(TAG, "Normal boot");
	#endif
    return 0;
}
and change the line:

Code: Select all

    if (bs->ota_info.offset != 0) {
to:

Code: Select all

    if (bs->ota_info.offset != 0 && !ForceFactoryBoot()) {
Thanks for detailed description regarding OTA.

I will let you know if need any help for that.

Re: FOTA help

Posted: Sat Dec 09, 2017 4:57 pm
by Ritesh
chegewara wrote:It is possible and its not as hard to implement, but in my opinion it is waste of flash space. Ive been "working" on similar approach lately and what i did is:
- one OTA partition which is used to keep factory firmware. factory firmware is basicaly used to download and flash new firmware to 2nd OTA
-one OTA partition to keep main application which will have minimal interface to check if new application is available and if is then switch to first ota partition which will perform update.

If you wish to have 3 partitions you can make similar implementation:
- one ota partition to keep firmware,
- two ota partitions to have application,
- esp-idf ota example write new application to unused ota partition, you can add option to check if its firmware partition, if it is then find next ota partition and perform ota update
Thanks for providing details.