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

Migrating from Keil to SES - Error with DFU INIT service

Hello Guys,,

I am trying to migrate my project form keil to segger embedded studio. My product is based on sdk 12.2.0, using softdevice s130 on nrf51822.
I searched for all the posts that helped in migrating to SES and able to successfully build my application project. But when flashing the build to my board
it is getting stuck at nrf_dfu_flash_erase function in dfu_init

I tried debugging and it is giving the error FS_ERR_INVALID_CFG in check_config(p_config) function. searched for the solution in the forum posts but nothing helped so far.
please help us to resolve as we are nearing production.


I am attaching my flash placement file for your reference

<!DOCTYPE Linker_Placement_File>
<Root name="Flash Section Placement">
  <MemorySegment name="$(FLASH_NAME:FLASH)">
    <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START:)" />
    <ProgramSection alignment="4" load="Yes" name=".fs_data" />
    <ProgramSection alignment="4" load="Yes" name=".init" />
    <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
    <ProgramSection alignment="4" load="Yes" name=".text" />
    <ProgramSection alignment="4" load="Yes" name=".dtors" />
    <ProgramSection alignment="4" load="Yes" name=".ctors" />
    <ProgramSection alignment="4" load="Yes" name=".rodata" />
    <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
    <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
    <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
    <ProgramSection alignment="4" load="Yes" name=".bootloaderSettings" />
    <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" runin=".fs_data_run" name=".fs_data" />
  </MemorySegment>
  <MemorySegment name="$(RAM_NAME:RAM);SRAM">
    <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START:$(SRAM_START:))" />
    <ProgramSection alignment="4" load="No" name=".fast_run" />
    <ProgramSection alignment="4" load="No" name=".data_run" />
    <ProgramSection alignment="4" load="No" name=".bss" />
    <ProgramSection alignment="4" load="No" name=".tbss" />
    <ProgramSection alignment="4" load="No" name=".tdata_run" />
    <ProgramSection alignment="4" load="No" name=".non_init" />
    <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
    <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack" />
    <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
    <ProgramSection alignment="4" size="__STACKSIZE__" load="No" name=".fs_data_run" address_symbol="__start_fs_data"  end_symbol="__stop_fs_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data"  end_symbol="__stop_fs_data" />
  </MemorySegment>
  <MemorySegment name="$(FLASH2_NAME:FLASH2)">
    <ProgramSection alignment="4" load="Yes" name=".text2" />
    <ProgramSection alignment="4" load="Yes" name=".rodata2" />
    <ProgramSection alignment="4" load="Yes" runin=".data2_run" name=".data2" />
  </MemorySegment>
  <MemorySegment name="$(RAM2_NAME:RAM2)">
    <ProgramSection alignment="4" load="No" name=".data2_run" />
    <ProgramSection alignment="4" load="No" name=".bss2" />
  </MemorySegment>
</Root>

Parents
  • The nrf_dfu_flash_erase documentation states that FS_ERR_INVALID_CFG is returned when the initialization of the fstorage module is invalid, i.e.  if the config pointer passed to fs_erase in nrf_dfu_flash_erase() is non-NULL and within section variable bounds.

    /**@brief Function for erasing data from flash (with or without the SoftDevice enabled).
     *
     * @param[in]  p_dest    The address of the first byte to be deleted.
     * @param[in]  num_pages The number of flash pages to be deleted.
     * @param[in]  callback  Pointer to the callback function.
     *
     * @retval  FS_SUCCESS              If the operation was successful.
     * @retval  FS_ERR_UNALIGNED_ADDR   If @p p_dest is not aligned to a page boundary.
     * @retval  FS_ERR_INVALID_ADDR     If @p p_dest does not point to the start of a flash page or the operation would
     *                                  go beyond the flash memory boundary.
     * @retval  FS_ERR_NOT_INITIALIZED  If the fstorage module is not initialized.
     * @retval  FS_ERR_INVALID_CFG      If the initialization of the fstorage module is invalid.
     * @retval  FS_ERR_NULL_ARG         If @p p_dest is NULL.
     * @retval  FS_ERR_INVALID_ARG      If @p num_pages is zero.
     * @retval  FS_ERR_QUEUE_FULL       If the internal operation queue of the fstorage module is full.
     */
    fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback);

    fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback)
    {
        fs_ret_t ret_val = FS_SUCCESS;
        NRF_LOG_INFO("Erasing: 0x%08x, num: %d\r\n", (uint32_t)p_dest, num_pages);
    
    #ifdef BLE_STACK_SUPPORT_REQD
    
        if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0)
        {
            // Check if there is a pending error
            if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0)
            {
                NRF_LOG_INFO("Erase: Failure since last\r\n");
                return FS_ERR_FAILURE_SINCE_LAST;
            }
    
            m_flags |= FLASH_FLAG_OPER;
            ret_val = fs_erase(&fs_dfu_config, p_dest, num_pages, (void*)callback);
    
            if (ret_val != FS_SUCCESS)
            {
                NRF_LOG_INFO("Erase failed: %d\r\n", ret_val);
                m_flags &= ~FLASH_FLAG_OPER;
                return ret_val;
            }
    
            // Set the flag to indicate ongoing operation
            m_flags |= FLASH_FLAG_OPER;
        }
        else
    #endif
        {
    #ifndef NRF51
            // Softdevice is not present or activated. Run the NVMC instead
            if (((uint32_t)p_dest & (CODE_PAGE_SIZE-1)) != 0)
            {
                NRF_LOG_INFO("Invalid address\r\n");
                return FS_ERR_UNALIGNED_ADDR;
            }
    #endif
    
            uint16_t first_page = ((uint32_t)p_dest / CODE_PAGE_SIZE);
            do
            {
                nrf_nvmc_page_erase((uint32_t)p_dest);
                p_dest += CODE_PAGE_SIZE/sizeof(uint32_t);
            }
            while(--num_pages > 0);
    
    
            if (callback)
            {
                #if (__LINT__ != 1)
                fs_evt_t evt =
                {
                    .id = FS_EVT_ERASE,
                    .p_context = (void*)callback,
                    .erase =
                    {
                        .first_page = first_page,
                        .last_page = ((uint32_t)p_dest / CODE_PAGE_SIZE)
                    }
                };
                callback(&evt, FS_SUCCESS);
                #else
                (void)first_page;
                #endif
            }
        }
    
        return ret_val;
    }

    Do you register the fs_dfu_config with FS_REGISTER_CFG Macro in your application?

    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
    };

    This should place the configuration variable in the section named "fs_data", which I can see in your linker script. 

    Best regards

    Bjørn

Reply
  • The nrf_dfu_flash_erase documentation states that FS_ERR_INVALID_CFG is returned when the initialization of the fstorage module is invalid, i.e.  if the config pointer passed to fs_erase in nrf_dfu_flash_erase() is non-NULL and within section variable bounds.

    /**@brief Function for erasing data from flash (with or without the SoftDevice enabled).
     *
     * @param[in]  p_dest    The address of the first byte to be deleted.
     * @param[in]  num_pages The number of flash pages to be deleted.
     * @param[in]  callback  Pointer to the callback function.
     *
     * @retval  FS_SUCCESS              If the operation was successful.
     * @retval  FS_ERR_UNALIGNED_ADDR   If @p p_dest is not aligned to a page boundary.
     * @retval  FS_ERR_INVALID_ADDR     If @p p_dest does not point to the start of a flash page or the operation would
     *                                  go beyond the flash memory boundary.
     * @retval  FS_ERR_NOT_INITIALIZED  If the fstorage module is not initialized.
     * @retval  FS_ERR_INVALID_CFG      If the initialization of the fstorage module is invalid.
     * @retval  FS_ERR_NULL_ARG         If @p p_dest is NULL.
     * @retval  FS_ERR_INVALID_ARG      If @p num_pages is zero.
     * @retval  FS_ERR_QUEUE_FULL       If the internal operation queue of the fstorage module is full.
     */
    fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback);

    fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback)
    {
        fs_ret_t ret_val = FS_SUCCESS;
        NRF_LOG_INFO("Erasing: 0x%08x, num: %d\r\n", (uint32_t)p_dest, num_pages);
    
    #ifdef BLE_STACK_SUPPORT_REQD
    
        if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0)
        {
            // Check if there is a pending error
            if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0)
            {
                NRF_LOG_INFO("Erase: Failure since last\r\n");
                return FS_ERR_FAILURE_SINCE_LAST;
            }
    
            m_flags |= FLASH_FLAG_OPER;
            ret_val = fs_erase(&fs_dfu_config, p_dest, num_pages, (void*)callback);
    
            if (ret_val != FS_SUCCESS)
            {
                NRF_LOG_INFO("Erase failed: %d\r\n", ret_val);
                m_flags &= ~FLASH_FLAG_OPER;
                return ret_val;
            }
    
            // Set the flag to indicate ongoing operation
            m_flags |= FLASH_FLAG_OPER;
        }
        else
    #endif
        {
    #ifndef NRF51
            // Softdevice is not present or activated. Run the NVMC instead
            if (((uint32_t)p_dest & (CODE_PAGE_SIZE-1)) != 0)
            {
                NRF_LOG_INFO("Invalid address\r\n");
                return FS_ERR_UNALIGNED_ADDR;
            }
    #endif
    
            uint16_t first_page = ((uint32_t)p_dest / CODE_PAGE_SIZE);
            do
            {
                nrf_nvmc_page_erase((uint32_t)p_dest);
                p_dest += CODE_PAGE_SIZE/sizeof(uint32_t);
            }
            while(--num_pages > 0);
    
    
            if (callback)
            {
                #if (__LINT__ != 1)
                fs_evt_t evt =
                {
                    .id = FS_EVT_ERASE,
                    .p_context = (void*)callback,
                    .erase =
                    {
                        .first_page = first_page,
                        .last_page = ((uint32_t)p_dest / CODE_PAGE_SIZE)
                    }
                };
                callback(&evt, FS_SUCCESS);
                #else
                (void)first_page;
                #endif
            }
        }
    
        return ret_val;
    }

    Do you register the fs_dfu_config with FS_REGISTER_CFG Macro in your application?

    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
    };

    This should place the configuration variable in the section named "fs_data", which I can see in your linker script. 

    Best regards

    Bjørn

Children
No Data
Related