FOTA help

remeshck
Posts: 6
Joined: Thu Apr 20, 2017 9:54 am

FOTA help

Postby remeshck » Mon Sep 25, 2017 12:54 pm

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

sukeshak
Posts: 39
Joined: Sat Aug 19, 2017 10:20 am

Re: FOTA help

Postby sukeshak » Sat Oct 07, 2017 5:46 pm


remeshck
Posts: 6
Joined: Thu Apr 20, 2017 9:54 am

Re: FOTA help

Postby remeshck » Wed Oct 11, 2017 12:14 pm

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

Ritesh
Posts: 642
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: FOTA help

Postby Ritesh » Fri Dec 08, 2017 5:55 pm

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.
Regards,
Ritesh Prajapati

User avatar
loboris
Posts: 467
Joined: Wed Dec 21, 2016 7:40 pm

Re: FOTA help

Postby loboris » Fri Dec 08, 2017 7:29 pm

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()) {
Last edited by loboris on Fri Dec 08, 2017 7:36 pm, edited 3 times in total.

chegewara
Posts: 532
Joined: Wed Jun 14, 2017 9:00 pm

Re: FOTA help

Postby chegewara » Fri Dec 08, 2017 7:33 pm

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

Ritesh
Posts: 642
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: FOTA help

Postby Ritesh » Sat Dec 09, 2017 4:56 pm

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.
Regards,
Ritesh Prajapati

Ritesh
Posts: 642
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: FOTA help

Postby Ritesh » Sat Dec 09, 2017 4:57 pm

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.
Regards,
Ritesh Prajapati

Return to “Sample Code”

Who is online

Users browsing this forum: No registered users and 2 guests