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 Hung Bui. I've figured out what was causing this. I'm using GCC as my compiler. I followed the experimental_ble_app_buttonless_dfu closely. The linker script provided with the example doesn't declare the .bootloaderSettings section so when the compiler reaches the part of nrf_dfu_settings.c where it allocates m_dfu_settings_buffer, it can't find the section. (I was also under the impression that the compiler was entering the #if defined (__CC_ARM ) section, but instead it enters #elif defined ( __GNUC__ )).

    Declaring the section in the application linker script, the application boots normally. This was also what was causing the CRC to be zero on boot.

Reply
  • Hi Hung Bui. I've figured out what was causing this. I'm using GCC as my compiler. I followed the experimental_ble_app_buttonless_dfu closely. The linker script provided with the example doesn't declare the .bootloaderSettings section so when the compiler reaches the part of nrf_dfu_settings.c where it allocates m_dfu_settings_buffer, it can't find the section. (I was also under the impression that the compiler was entering the #if defined (__CC_ARM ) section, but instead it enters #elif defined ( __GNUC__ )).

    Declaring the section in the application linker script, the application boots normally. This was also what was causing the CRC to be zero on boot.

Children
No Data
Related