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

FS_ERR_UNALIGNED_ADDR with Buttonless DFU

Hi, I'm working on porting my application from SDK 11.0 to 12.2.0 and I have a problem initializing the buttonless DFU service. I've flashed the secure bootloader and appropriate settings. The bootloader itself is working correctly (I can upload a Nordic test image just fine).

If I add the BLE DFU service during services_init() the device resets. I've narrowed the fault down to this portion of the nrf_dfu_settings.c:

void nrf_dfu_settings_init(void)
{
    NRF_LOG_INFO("running nrf_dfu_settings_init\r\n");

    volatile uint32_t crc;

    flash_operation_pending = false;

    // Copy the DFU settings out of flash and into a buffer in RAM.
    memcpy((void*)&s_dfu_settings, &m_dfu_settings_buffer[0], sizeof(nrf_dfu_settings_t));

    if(s_dfu_settings.crc != 0xFFFFFFFF)
    {
        // CRC is set. Content must be valid
        crc = nrf_dfu_settings_calculate_crc();
        if(crc == s_dfu_settings.crc)
        {
            return;
        }
    }

    // Reached if nothing is configured or if CRC was wrong
    NRF_LOG_INFO("!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!\r\n");
    memset(&s_dfu_settings, 0x00, sizeof(nrf_dfu_settings_t));
    s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION;
    APP_ERROR_CHECK(nrf_dfu_settings_write(NULL));
}


ret_code_t nrf_dfu_settings_write(dfu_flash_callback_t callback)
{
    ret_code_t err_code = FS_SUCCESS;
    NRF_LOG_INFO("Erasing old settings at: 0x%08x\r\n", (uint32_t)&m_dfu_settings_buffer[0]);

    // Wait for any ongoing operation (because of multiple calls to nrf_dfu_settings_write)
    wait_for_pending();
    
    flash_operation_pending = true;
    m_callback = callback;
    
    do 
    {
        wait_for_queue();
        
        // Not setting the callback function because ERASE is required before STORE
        // Only report completion on successful STORE.
        err_code = nrf_dfu_flash_erase((uint32_t*)&m_dfu_settings_buffer[0], 1, NULL);
        
    } while (err_code == FS_ERR_QUEUE_FULL);
    
    
    if (err_code != FS_SUCCESS)
    {
        NRF_LOG_ERROR("Erasing from flash memory failed.\r\n");
        flash_operation_pending = false;
        return NRF_ERROR_INTERNAL;
    }

    s_dfu_settings.crc = nrf_dfu_settings_calculate_crc();

    NRF_LOG_INFO("Writing 0x%08x words\r\n", sizeof(nrf_dfu_settings_t)/4);

    static nrf_dfu_settings_t temp_dfu_settings;
    memcpy(&temp_dfu_settings, &s_dfu_settings, sizeof(nrf_dfu_settings_t));

    do 
    {
        wait_for_queue();
        
        err_code = nrf_dfu_flash_store((uint32_t*)&m_dfu_settings_buffer[0],
                                       (uint32_t*)&temp_dfu_settings,
                                       sizeof(nrf_dfu_settings_t)/4,
                                       dfu_settings_write_callback);

    } while (err_code == FS_ERR_QUEUE_FULL);
    
    if (err_code != FS_SUCCESS)
    {
        NRF_LOG_ERROR("Storing to flash memory failed.\r\n");
        flash_operation_pending = false;
        return NRF_ERROR_INTERNAL;
    }

    NRF_LOG_INFO("Writing settings...\r\n");
    return NRF_SUCCESS;
}

The stored CRC is just 0, so it does not match the calculated one. Thus the application resets the bootloader settings. This alarms me since nrfutil reports a CRC when I generate the settings hex file.

But anyway, the value returned by this line:

err_code = nrf_dfu_flash_erase((uint32_t*)&m_dfu_settings_buffer[0], 1, NULL);

is FS_ERR_UNALIGNED_ADDR, and I'm not quite sure what's going on. The bootloader settings address is configured as 0x0007F000, which should be aligned with a a page boundary.

Parents
  • Hi Dingari,

    Could you explain a little bit more on your porting ? Do you plan to also DFU update the bootloader from SDK v11 to SDK v12 (from legacy bootloader to secure bootloader ? )

    "The stored CRC is just 0" Do you mean it's the initial CRC, if that what you meant then it's normal. If you already flashed the bootlaoder setting hex you generate, then the CRC when the bootloader start should be the same as the bootloader setting's CRC.

    Regarding the issue with nrf_dfu_flash_erase() could you step into the code and check if the destination p_page_addr actually address 0x0007F000?

    I would recommend to switch to DFU bootloader in SDK v13. In this latest version we don't write to flash but use retention RAM, which in my view, cleaner and simpler.

Reply
  • Hi Dingari,

    Could you explain a little bit more on your porting ? Do you plan to also DFU update the bootloader from SDK v11 to SDK v12 (from legacy bootloader to secure bootloader ? )

    "The stored CRC is just 0" Do you mean it's the initial CRC, if that what you meant then it's normal. If you already flashed the bootlaoder setting hex you generate, then the CRC when the bootloader start should be the same as the bootloader setting's CRC.

    Regarding the issue with nrf_dfu_flash_erase() could you step into the code and check if the destination p_page_addr actually address 0x0007F000?

    I would recommend to switch to DFU bootloader in SDK v13. In this latest version we don't write to flash but use retention RAM, which in my view, cleaner and simpler.

Children
No Data
Related