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

FS_REGISTER_CFG sets my fs_config_t with incorrect values

I am using the example on sdk12.3/examples/ble_peripheral/experimental_ble_app_buttonless_dfu and copied the relevant parts to my app.

It is now apparently working. The bootloader settings are deleted when I connect top the device, subscribe to the dfu characteristic and then write "request" to it. The only problem is that I need to reset the device manually by turning off/on the power and when it boots, the bootloader fails the crc check and goes into dfu mode.

While trying to understand why the reason for the reset not being called on ble_dfu:on_disconnect():

static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt)
{
    if (p_dfu->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle)
    {
        return;
    }

    p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;

    if (p_dfu->is_waiting_for_disconnection)
    {
        NVIC_SystemReset();
    }
}

And that is because p_dfu->is_waiting_for_disconnection is false when I disconnect the android app, after executing the steps explained above.

The reason is that the flash_callback is not called. I tracked this to fs_sys_event_handler(sys_evt) not being called, so I uncommented the call to "fs_sys_event_handler(sys_evt)" on main.c:sys_evt_dispatch(), and then I got a bit further: the result of the fs operation is now being reported, but on:

static void send_event(fs_op_t const * const p_op, fs_ret_t result)
{
    fs_evt_t evt;
    memset(&evt, 0x00, sizeof(fs_evt_t));

    switch (p_op->op_code)
    {
        case FS_OP_STORE:
            evt.id                 = FS_EVT_STORE;
            evt.store.p_data       = p_op->store.p_dest;
            evt.store.length_words = p_op->store.length_words;
            break;

        case FS_OP_ERASE:
            evt.id               = FS_EVT_ERASE;
            evt.erase.first_page = p_op->erase.page - p_op->erase.pages_erased;
            evt.erase.last_page  = p_op->erase.page;
            break;

        default: 
            // Should not happen.
            break;
    }
    evt.p_context = p_op->p_context;

    p_op->p_config->callback(&evt, result);
}

the call to p_op->p_config->callback(&evt, result); is failing, because the address of p_op->p_config->callback is 0x1040fff7, instead of 0x00022875.

More on this bellow...

I noticed that the call to FS_REGISTER_CFG:

FS_REGISTER_CFG(fs_config_t fs_dfu_config) =
{
    .callback       = fs_evt_handler,            // Function for event callbacks.
    .p_start_addr   = (uint32_t*)MBR_SIZE,
    .p_end_addr     = (uint32_t*)(BOOTLOADER_SETTINGS_ADDRESS + CODE_PAGE_SIZE)
};

Apparently the correct values are not being set.

Initially the p_start_addr and p_end_addr were being set incorrecly, and I "fixed" that by adding code to nrf_dfu_flash_init() on nrf_dfu_flash_buttonless.c (this is code from the example)

Original:

uint32_t nrf_dfu_flash_init(bool sd_enabled)
{
    m_flags = FLASH_FLAG_SD_ENABLED;
    return NRF_SUCCESS;
}

My changes:

uint32_t nrf_dfu_flash_init(bool sd_enabled)
{
    fs_dfu_config.p_start_addr   = (uint32_t*)MBR_SIZE;
    fs_dfu_config.p_end_addr     = (uint32_t*)(BOOTLOADER_SETTINGS_ADDRESS + CODE_PAGE_SIZE);

    m_flags = FLASH_FLAG_SD_ENABLED;
    return NRF_SUCCESS;
}

But for some reason, and without me having changed anything that I can think of that might have made the correct values being assigned to p_start_addr and p_end_addr, these changes are no longer needed. This is intriguing.

But on reporting the status of the fstorage operations, the executing is hanging. I tracked this down to the value of .callback on the same structure.

I added the following:

uint32_t nrf_dfu_flash_init(bool sd_enabled)
{
    fs_config_t x = {
      .callback = fs_evt_handler
    };
    
    m_flags = FLASH_FLAG_SD_ENABLED;
    return NRF_SUCCESS;
}

And by placing a breakpoint on "m_flags = FLASH_FLAG_SD_ENABLED;", i can see that:

x.callback = 0x00022875

while:

fs_dfu_config.callback = 0x1040fff7

The execution is hanging at 0x1040fff6, which has no code.

I am wondering what is going on here? I still don't understand why FS_REGISTER_CFG sets the wrong values, first to the start and end addresses and now to the callback function pointer. Can you provide some suggestions on how to fix this?

Best regards,

Ricardo

Related