- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On an STM32F4 based board...
When hitting ota2_bootloader.c::ota2_failsafe_app_load() the entry point is a flash address 0x800c3e5 but it hasn't been loaded into internal flash from SFlash. I see ota2_failsafe_app_load() erasing (internal?) flash:
/* Erase the application area */
result = ota2_failsafe_app_area_erase( flash_location, &header );
Then reading into RAM from flash:
result = ota2_failsafe_app_read( flash_location, (uint8_t*)prog_header.physical_address, prog_header.data_offset, prog_header.data_size_in_file );
But danged if it's obvious how internal flash get's written! It is quite clear in wiced_waf_common.c::wiced_waf_app_load():
result = platform_load_app_chunk( app_header_location, offset, (void*) prog_header.physical_address, prog_header.data_size_in_file );
Thanks!
Geoff
Solved! Go to Solution.
- Labels:
-
WICED Studio Wi-Fi Combo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Just to ensure, have you followed section-8 "Adding OTA2 to a new platform" of WICED OTA2 Update Support provided in Wiced Studio? Location-
43xxx_Wi-Fi\doc\WICED-OTA2.pdf
Thanks
Aditi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Could you try to post your code or the complete log output? We need more information to identify the cause.
Best regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm using WICED-SDK 6.4 and the stock ota2_bootloader.c and ota2_failsafe.c (which is stuffed into sflash). The only change made was for test purposes, I added:
dct_ota2_config.boot_type = OTA2_BOOT_FAILSAFE_FACTORY_RESET;
Simply so I can verify it would load and run failsafe. Previously, I had used ModusToolbox to run ota2_failsafe without any problem. There's no output because the ota2_bootloader does select the failsafe path, but then jumps into a hardfault. That led me to wonder how the sflash image was being copied into iflash. Unless the ota2_failsafe image is supposed to run entirely out of SRAM, I couldn't follow the ota2_bootloader logic.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is the fix... sorry not pretty:
uint8_t buff[ 64 ];
while ( size > 0 )
{
uint32_t write_size = MIN( sizeof(buff), size);
result = ota2_failsafe_app_read( flash_location, buff, offset, write_size );
platform_write_flash_chunk( (uint32_t) physical_address, buff, write_size );
The original code did not read into an SRAM buffer and then into iflash (with platform_write_flash_chunk). The only way it might have worked is if the failsafe was linked to execute out of SRAM.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Just to ensure, have you followed section-8 "Adding OTA2 to a new platform" of WICED OTA2 Update Support provided in Wiced Studio? Location-
43xxx_Wi-Fi\doc\WICED-OTA2.pdf
Thanks
Aditi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To get to as far as I got, clearly I had to perform the steps in Section 8.
To re-state, the code in ota2_bootloader.c:ota2_failsafe_app_load() does not copy the failsafe app from sflash into iflash.
static wiced_result_t ota2_failsafe_app_load( uint32_t flash_location, uint32_t* entry_point )
{
wiced_result_t result = WICED_SUCCESS;
uint32_t i;
elf_header_t header;
elf_program_header_t prog_header;
/* assume pointer is good (only called from within this file) and assume error */
*entry_point = 0;
/* Read the image header */
result = ota2_failsafe_app_read( flash_location, (uint8_t*) &header, 0, sizeof( header ) );
if (result != WICED_SUCCESS)
{
return result;
}
/* Quick ELF header validity check */
if (header.ident.magic != ELF_MAGIC_NUMBER)
{
return result;
}
/* Erase the application area */
result = ota2_failsafe_app_area_erase( flash_location, &header );
if (result != WICED_SUCCESS)
{
return result;
}
#if 1
/*
* The code provided by WICED tries to write from sflash directly to the physical_address which is not possibly with flash.
* This code follows the implementation in wiced_waf_app_load() looping through each elf section and is simliar platform_copy_app_to_iflash() but
* our code ignores the header that wiced_apps_read() is looking for (since it is missing).
*
*/
for ( i = 0; i < header.program_header_entry_count; i++ )
{
wiced_bool_t is_elf;
//read the elf header
unsigned long offset = header.program_header_offset + header.program_header_entry_size * (unsigned long) i;
result = ota2_failsafe_app_read( flash_location, (uint8_t*) &prog_header, offset, sizeof( prog_header ) );
if ( result != WICED_SUCCESS )
{
return WICED_ERROR;
}
//only load code segments
is_elf = ota2_failsafe_is_elf_segment_load( &prog_header );
if ( is_elf == WICED_FALSE )
{
continue;
}
offset = prog_header.data_offset;
int32_t size = prog_header.data_size_in_file;
uint8_t* physical_address = (uint8_t*)prog_header.physical_address;
uint8_t buff[ 64 ];
while ( size > 0 )
{
uint32_t write_size = MIN( sizeof(buff), size);
result = ota2_failsafe_app_read( flash_location, buff, offset, write_size );
platform_write_flash_chunk( (uint32_t) physical_address, buff, write_size );
//check our data written to flash is good.
if (memcmp((char *)physical_address, buff, write_size))
{
offset = 0;
return WICED_ERROR;
}
offset += write_size;
physical_address += write_size;
size -= write_size;
}
result = WICED_SUCCESS;
}
#else // incorrect WICED implementation
for ( i = 0; i < header.program_header_entry_count; i++ )
{
wiced_bool_t is_elf;
unsigned long offset = header.program_header_offset + header.program_header_entry_size * (unsigned long) i;
result = ota2_failsafe_app_read( flash_location, (uint8_t*) &prog_header, offset, sizeof( prog_header ) );
is_elf = ota2_failsafe_is_elf_segment_load( &prog_header );
if ( is_elf == WICED_FALSE )
{
continue;
}
result = ota2_failsafe_app_read( flash_location, (uint8_t*)prog_header.physical_address, prog_header.data_offset, prog_header.data_size_in_file );
if (result != WICED_SUCCESS)
{
break;
}
}
#endif
if (result == WICED_SUCCESS)
{
/* return the program entry point */
*entry_point = header.entry;
}
return result;
}