This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Start Bootloader From App

I'm trying to create a method so a users can initiate an OTA update from a paired device. To that end I've written something which is supposed to invalidate the data at the BOOTLOADER_SETTINGS_ADDRESS to invalidate the current app and then call a system reset to run through the bootloader. Once working I will call this routine (start_bootloader()) on a given event from the paired device.

My problem is I can't understand pstorage and how to use it to invalidate the data at the BOOTLOADER_SETTINGS_ADDRESS. In looking through some examples (in the bootloader code for example, which most of the following is from) I can't see how the code actually specifies the BOOTLOADER_SETTINGS_ADDRESS as where to write the data. I see how it gets the data from that address.

The code below does not throw any errors it just does nothing. When I break at the sd_nvic_SystemReset(); call no memory locations have been affected and the app just restarts.

Note that I do NOT have a bootloader installed. I have set up to flash a device with softdevice, application and bootloader, setting the BOOTLOADER_SETTINGS_ADDRESS correctly and the BOOT_ADDR correctly so that everything works (i.e. it starts up in the application). If a corrupt the data used to flash the BOOTLOADER_SETTINGS_ADDRESS it goes to the bootloader and I can OTA the applications.

So what I'm asking is what am I doing wrong with pstorage below so that it is NOT changing the BOOTLOADER_SETTINGS_ADDRESS.

   typedef enum
{
    BOOTLOADER_UPDATING,
    BOOTLOADER_SETTINGS_SAVING,
    BOOTLOADER_COMPLETE,
    BOOTLOADER_TIMEOUT,
    BOOTLOADER_RESET,
} bootloader_status_t;


static pstorage_handle_t        m_bootsettings_handle;  /**< Pstorage handle to use for registration and identifying the bootloader module on subsequent calls to the pstorage module for load and store of bootloader setting in flash. */
static bootloader_status_t      m_update_status;        /**< Current update status for the bootloader module to ensure correct behaviour when updating settings and when update completes. */

static void pstorage_callback_handler(pstorage_handle_t * handle, uint8_t op_code, uint32_t result, uint8_t * p_data, uint32_t data_len)
{
    // Do Nothing For Now
    APP_ERROR_CHECK(result);
}



/*@brief Function for access to bootloader setting */

void bootloader_util_settings_get(const bootloader_settings_t** pp_bootloader_settings)
{
    // Read only pointer to bootloader settings in flash.
    *pp_bootloader_settings = (bootloader_settings_t*)BOOTLOADER_SETTINGS_ADDRESS;
}


void bootloader_settings_save(bootloader_settings_t * p_settings)
{
    uint32_t err_code = pstorage_clear(&m_bootsettings_handle, sizeof(bootloader_settings_t));
    APP_ERROR_CHECK(err_code);
    
    err_code = pstorage_store(&m_bootsettings_handle,
                              (uint8_t *)p_settings,
                              sizeof(bootloader_settings_t),
                              0);
    APP_ERROR_CHECK(err_code);
}

void start_bootloader()
{
    uint32_t                err_code = NRF_SUCCESS;
    pstorage_module_param_t storage_params;
    
    //    sd_softdevice_disable();
    
    storage_params.cb          = pstorage_callback_handler;
    storage_params.block_size  = sizeof(bootloader_settings_t);
    storage_params.block_count = 1;
    
    err_code = pstorage_init();
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    err_code = pstorage_register(&storage_params, &m_bootsettings_handle);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    //    m_bootsettings_handle.block_id = BOOTLOADER_SETTINGS_ADDRESS;
    static bootloader_settings_t settings;
    const bootloader_settings_t * p_bootloader_settings;
    
    bootloader_util_settings_get(&p_bootloader_settings);
    settings.bank_0_crc  = p_bootloader_settings->bank_0_crc;
    settings.bank_0_size = p_bootloader_settings->bank_0_size;
    settings.bank_0      = BANK_VALID_APP;
    settings.bank_1      = p_bootloader_settings->bank_1;
    
    bootloader_settings_save(&settings);
    
    sd_nvic_SystemReset();
    
}
Related