OTA clarification

imtiaz
Posts: 106
Joined: Wed Oct 26, 2016 1:34 am

Re: OTA clarification

Postby imtiaz » Fri Feb 24, 2017 12:30 am

Hi Angus,

Even if the ota image is not present at all and you set the OTA data to say boot from that OTA image - the bootloader will attempt to boot from it and then fail verify and then do nothing. As long as the partition table has the OTA partitions that is...

Code: Select all

 if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err);
        return 0;
    }
So I've added a bit of code in the bootloader so that if the return is 0 - it will then attempt to load factory image

Code: Select all

if(unpack_load_app(&load_part_pos) == 0)
    {
    		ESP_LOGE(TAG, "Trying to boot to factory");
    		load_part_pos = bs.factory;
    		if(unpack_load_app(&load_part_pos) == 0)
    		{
    			ESP_LOGE(TAG, "CATOSTROPHIC FAILURE - Factory image failed verify"); //cant do anything if factory image has failed
    		}
    }
and Ive also added a failsafe option so if a button is held down for 10 seconds on bootup the bootloader will load the factory image.

So in the meantime how can I keep my bootloader changes since it is part of the IDF ? I really dont want to have my own repository for this.

Thanks
Imtiaz

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: OTA clarification

Postby ESP_Angus » Fri Feb 24, 2017 2:02 am

imtiaz wrote:Hi Angus,

Even if the ota image is not present at all and you set the OTA data to say boot from that OTA image - the bootloader will attempt to boot from it and then fail verify and then do nothing. As long as the partition table has the OTA partitions that is...
Right, that's not good and we will fix it. What I meant to point out is that (at least with recent IDF) esp_ota_set_boot_partition() should fail to set that OTA partition as the boot partition, if the image doesn't verify.
imtiaz wrote: So in the meantime how can I keep my bootloader changes since it is part of the IDF ? I really dont want to have my own repository for this.
You can override components on a per-project basis. In your project directory, make a PROJECT_DIR/components/bootloader directory and copy the contents of IDF_PATH/components/bootloader to here. This bootloader component will be used in preference to the IDF one.

When updating IDF, you'll need to manually keep an eye out for other updates to the bootloader source and roll these into your copy of the component.

imtiaz
Posts: 106
Joined: Wed Oct 26, 2016 1:34 am

Re: OTA clarification

Postby imtiaz » Fri Feb 24, 2017 2:27 am

You can override components on a per-project basis. In your project directory, make a PROJECT_DIR/components/bootloader directory and copy the contents of IDF_PATH/components/bootloader to here. This bootloader component will be used in preference to the IDF one.
Thats a brilliant feature - well done

hybryd
Posts: 2
Joined: Mon Aug 07, 2017 7:41 pm

Re: OTA clarification

Postby hybryd » Fri Aug 18, 2017 8:13 am

Hi Imtiaz,
Can you share your button override code that you added to the custom bootloader?

and Ive also added a failsafe option so if a button is held down for 10 seconds on bootup the bootloader will load the factory image.

imtiaz
Posts: 106
Joined: Wed Oct 26, 2016 1:34 am

Re: OTA clarification

Postby imtiaz » Mon Oct 16, 2017 8:37 pm

Hi hybrid,

sorry I have been away from the forums - do you still need this?

cmorgan
Posts: 89
Joined: Thu Aug 24, 2017 12:52 am

Re: OTA clarification

Postby cmorgan » Sun Oct 22, 2017 11:07 pm

imtiaz wrote:Hi hybrid,

sorry I have been away from the forums - do you still need this?
I could use it here, I'm in a similar spot and would like to re-use the 'boot' mode switch to initiate a factory image boot.

imtiaz
Posts: 106
Joined: Wed Oct 26, 2016 1:34 am

Re: OTA clarification

Postby imtiaz » Sun Nov 05, 2017 6:41 pm

1 - copy the entire bootloader component from the idf into your application
2 - add the following functon somewhere and repurpose for your button input pin and timeout requirements

Code: Select all

/**
 *  @function :     ForceFactoryBoot
 *  @description:   Add by Imtiaz @ Syrp for failsafe mode
 *
 *  @inputs:        void
 */
static uint8_t ForceFactoryBoot(void)
{
    #define GPIO_INPUT_FORCE_FACTORY     4
    uint8_t timer = 0;
      gpio_pad_select_gpio(GPIO_INPUT_FORCE_FACTORY);
     ets_delay_us(10000); //delay 10 msecs
    while(GPIO_INPUT_GET(GPIO_INPUT_FORCE_FACTORY))
    {
    	ESP_LOGE(TAG, "OTA Pin is Active : %d!",timer);
    	ets_delay_us(1000000);
    	timer++;
    	if(timer == 10)
    	{
    		ESP_LOGE(TAG, "Forcing Factory : %d!",GPIO_INPUT_GET(GPIO_INPUT_FORCE_FACTORY));
    		return 1;
    	}
    }
    return 0;
}
3 - add this line of code to line # 332 in the file

Code: Select all

if (bs->ota_info.offset != 0 && !ForceFactoryBoot())
should do it

cmorgan
Posts: 89
Joined: Thu Aug 24, 2017 12:52 am

Re: OTA clarification

Postby cmorgan » Mon Nov 20, 2017 7:49 pm

Thanks for the pointers and the example code!

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

Re: OTA clarification

Postby chegewara » Tue Nov 21, 2017 3:56 am

Its nice solution and i would use it, but what if i dont want to alter bootloader? Ive been thinking today a while. First solution i have found and make it working was to install OTA app on factory partition, add snippet to main app which will erase otadata partition with

Code: Select all

spi_flash_erase_range()
if during reset i press button on pin i chose. Its some workaround and it works nicely, especially with boot wifi app.
But then i figured out better way. There is nowhere said that we HAVE to have factory partition. We can just have 2 ota partitions and one of them use like factory and the other like ota partition. This way we can have first partition small and for main app bigger. Now we dont have to use any workaround because we have api to switch between ota partitions.
Just thought i will share this story and this may help someone.

davdav
Posts: 208
Joined: Thu Nov 17, 2016 2:33 pm

Re: OTA clarification

Postby davdav » Mon Mar 19, 2018 12:07 pm

Hi,

I re-open this thread to have confirmation we can have only FACTORY and 1 OTA partition.

Our project is getting bigger (>1MB) and we need at least 1MB for FAT filesystem so we would like to have just 1 OTA partion and switch between factory and that OTA partition (both of them of 1.5MB).


Do you think the pseudo-code below is it ok?

Code: Select all

const esp_partition_t *factory //Here need to define all information for factory partition (type,subtype,address)

//Check current partition
const esp_partition_t *running = esp_ota_get_running_partition();

if (running->subtype == ESP_PARTITION_SUBTYPE_APP_OTA_0)
{
	//If partition is ota_0, then set next update to factory partition
	update_partition = esp_ota_get_next_update_partition(factory);
}

Thanks

Who is online

Users browsing this forum: abbas1375, Majestic-12 [Bot] and 92 guests