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

FDS_ERR_NO_PAGES in fds_init() with DFU

Hello,

I am using SDK16, Softdevice S140 with SES.

I am trying to add DFU functionality in my application and leaving only the activation of the new firmware to secure bootloader(which I achieved by excluding "nrf_dfu.c" and making NRF_BL_DFU_ALLOW_UPDATE_FROM_APP 1).

I also have these defines in bootloader:

#define NRF_DFU_APP_DATA_AREA_SIZE 12288(in sdk_config.h)

#define DFU_APP_DATA_RESERVED      NRF_DFU_APP_DATA_AREA_SIZE (in nrf_dfu_types.h)

In application:


#define FDS_VIRTUAL_PAGES 3
#define FDS_VIRTUAL_PAGE_SIZE 1024
#define FDS_VIRTUAL_PAGES_RESERVED 0

When I ran application, The error came FDS_ERR_NO_PAGES(pm_init --> pds_init --> fds_init). The reason I found that the start address for FDS pages came wrong(it came 0xfb000) because bootloader address(it came 0xffffffff) was not set(It should be in UICR register). I am not sure but I guess my mistake was - I first programmed Bootloader and then the application which erased the UICR.

So, I used mergehex but then it gave error "The hex files cannot be merged since there are conflicts."

My settings are:

In application:

FLASH_PH_START=0x0

FLASH_PH_SIZE=0x100000

RAM_PH_START=0x20000000

RAM_PH_SIZE=0x40000

FLASH_START=0x27000

FLASH_SIZE=0xca000

RAM_START=0x20003910

RAM_SIZE=0x3c6f0

In Bootloader:

FLASH_PH_START=0x0

FLASH_PH_SIZE=0x100000

RAM_PH_START=0x20000000

RAM_PH_SIZE=0x40000

FLASH_START=0xf1000

FLASH_SIZE=0xd000

RAM_START=0x20005968

RAM_SIZE=0x3a698

(The flash area for bootloader starts where the area of application ends!)

I have set linker->memory segment as below for the bootloader as well as the application:

FLASH RX 0x0 0x100000;RAM RWX 0x20000000 0x40000;uicr_bootloader_start_address RX 0x10001014 0x4;bootloader_settings_page RX 0x000FF000 0x1000;uicr_mbr_params_page RX 0x10001018 0x4;mbr_params_page RX 0x000FE000 0x1000

I am not sure whether these settings are correct or not.

Kindly guide me through. Thank you!

Parents
  • Hi Vishwas, 

    Could you let me know the reason why the application would erase the UICR ? It's not something you should do as you already found that it erased the start address of the bootloader. 

    If you really need to erase the bootloader,  you would need to backup the data there in the UICR and rewrite after you erased. 

    However, from SDK v15.3 the address of the bootloader is also stored in the MBR_BOOTLOADER_ADDR, in addition to the UICR. You may want to double check the BOOTLOADER_ADDRESS macro to check why it got 0xFFFFFFFF.

    If you store something in the UICR in the application  try to avoid having it at the same address that used by the bootloader. Don't do --sectorerase when you flash the application. 

  • Hello Hung Bui,

    I am not intentionally erasing the UICR. It was my guess that it must be erased somehow. But I was wrong as in UICR, NRFFW[1] which is MBR_PARAMS_PAGE_ADDRESS stays intact(0x000FE000)

    Don't do --sectorerase when you flash the application. 

    I am not using nrfjprog for flashing. I am simply using Build->Build and Run from SES: first the bootloader program and then the application. Is it the wrong way when there is a bootloader?

    I also checked MBR_BOOTLOADER_ADDR(0xFF8) as well as MBR_PARAMS_PAGE_ADDRESS(0xFFC).

    When I put bootloader into debug mode, the first function of bootloader, nrf_bootloader_mbr_addrs_populate() does not write anything to both addresses, 0xFF8 and 0xFFC. I can only see 0xFFFFFFFF in debug mode. But I can see NRFFW[0] as 0x000F10000 and NRFFW[1] as 0x000FE000.

    Then, after programming application, in debug mode, MBR_PARAMS_PAGE_ADDRESS, 0x000FE000, is correctly taken from UICR(NRFFW[1]) but fetching bootloader address fails as there is no value in UICR NRFFW[0] and MBR_BOOTLOADER_ADDR was not written in the first place only.

  • HI Vishwas, 

    Please try to test with such step by step as follow: 
    1. Only flash softdevice and bootloader. Verify if UICR->NRFFW[0] is written correctly or not. Verify if MBR_BOOTLOADER_ADDR is written correctly or not. 

    2. Flash application using nrfjprog --program app.hex. Verify UICR->NRFFW[0] and MBR_BOOTLOADER_ADDR. Please use nrfjprog --memrd to read memory out. 

    I don't think the bootloader would be able to run normally if the address is not written correctly. 

    I assume you know that you would need to generate and flash the bootloader setting to be able to run the application after you flash it directly instead of doing DFU. 

  • 1. Only flash softdevice and bootloader. Verify if UICR->NRFFW[0] is written correctly or not. Verify if MBR_BOOTLOADER_ADDR is written correctly or not. 

    I programmed bootloader and SD from SES. I checked Memory regions(0xFF8 and 0xFFC) as well as UICR->NRFFW[0] with nrfjprog --memrd and they are written correctly.

    2. Flash application using nrfjprog --program app.hex. Verify UICR->NRFFW[0] and MBR_BOOTLOADER_ADDR. Please use nrfjprog --memrd to read memory out. 

    While programming application with nrfjprog -program, I got the error:

    Parsing hex file.
    Reading flash area to program to guarantee it is erased.
    ERROR: The area to write is not erased.

    I assume you know that you would need to generate and flash the bootloader setting to be able to run the application after you flash it directly instead of doing DFU. 

    When I will merge bootloader and application file to load as a single file, there would be default bootloader settings and that is sufficient, isn't it?

  • 1. Only flash softdevice and bootloader. Verify if UICR->NRFFW[0] is written correctly or not. Verify if MBR_BOOTLOADER_ADDR is written correctly or not. 

    I programmed bootloader and SD from SES. I checked Memory regions(0xFF8 and 0xFFC) as well as UICR->NRFFW[0] with nrfjprog --memrd and they are written correctly.

    2. Flash application using nrfjprog --program app.hex. Verify UICR->NRFFW[0] and MBR_BOOTLOADER_ADDR. Please use nrfjprog --memrd to read memory out. 

    While programming application with nrfjprog -program, I got the error:

    Parsing hex file.
    Reading flash area to program to guarantee it is erased.
    ERROR: The area to write is not erased.

    Don't I need to relocate vector table? Or is it done with FLASH_START macro?

    I assume you know that you would need to generate and flash the bootloader setting to be able to run the application after you flash it directly instead of doing DFU. 

    When I will merge bootloader and application file to load as a single file, there would be default bootloader settings and that is sufficient, isn't it?

    EDIT:

    I want to add that while porting DFU functionality to my application, I got the error:

    Output/Release/Exe/ble_app_beacon_pca10056_s140.elf section `.bootloader_settings_page' will not fit in region `UNPLACED_SECTIONS'

    region `UNPLACED_SECTIONS' overflowed by 8192 bytes

    So I updated the linker XML file.

    <!DOCTYPE Linker_Placement_File>
    <Root name="Flash Section Placement">
      <MemorySegment name="FLASH" start="$(FLASH_PH_START)" size="$(FLASH_PH_SIZE)">
        <ProgramSection load="no" name=".reserved_flash" start="$(FLASH_PH_START)" size="$(FLASH_START)-$(FLASH_PH_START)" />
        <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START)" />
        <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" keep="Yes" load="Yes" name=".sdh_soc_observers" inputsections="*(SORT(.sdh_soc_observers*))" address_symbol="__start_sdh_soc_observers" end_symbol="__stop_sdh_soc_observers" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_ble_observers" inputsections="*(SORT(.sdh_ble_observers*))" address_symbol="__start_sdh_ble_observers" end_symbol="__stop_sdh_ble_observers" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".pwr_mgmt_data" inputsections="*(SORT(.pwr_mgmt_data*))" address_symbol="__start_pwr_mgmt_data" end_symbol="__stop_pwr_mgmt_data" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_state_observers" inputsections="*(SORT(.sdh_state_observers*))" address_symbol="__start_sdh_state_observers" end_symbol="__stop_sdh_state_observers" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_stack_observers" inputsections="*(SORT(.sdh_stack_observers*))" address_symbol="__start_sdh_stack_observers" end_symbol="__stop_sdh_stack_observers" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_req_observers" inputsections="*(SORT(.sdh_req_observers*))" address_symbol="__start_sdh_req_observers" end_symbol="__stop_sdh_req_observers" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_queue" inputsections="*(.nrf_queue*)" address_symbol="__start_nrf_queue" end_symbol="__stop_nrf_queue" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_balloc" inputsections="*(.nrf_balloc*)" address_symbol="__start_nrf_balloc" end_symbol="__stop_nrf_balloc" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".cli_command" inputsections="*(.cli_command*)" address_symbol="__start_cli_command" end_symbol="__stop_cli_command" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".crypto_data" inputsections="*(SORT(.crypto_data*))" address_symbol="__start_crypto_data" end_symbol="__stop_crypto_data" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_const_data" inputsections="*(SORT(.log_const_data*))" address_symbol="__start_log_const_data" end_symbol="__stop_log_const_data" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_backends" inputsections="*(SORT(.log_backends*))" address_symbol="__start_log_backends" end_symbol="__stop_log_backends" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections" address_symbol="__start_nrf_sections" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".cli_sorted_cmd_ptrs"  inputsections="*(.cli_sorted_cmd_ptrs*)" runin=".cli_sorted_cmd_ptrs_run"/>
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".fs_data"  inputsections="*(.fs_data*)" runin=".fs_data_run"/>
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".dfu_trans" inputsections="*(SORT(.dfu_trans*))" address_symbol="__start_dfu_trans" end_symbol="__stop_dfu_trans" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".svc_data" inputsections="*(.svc_data*)" address_symbol="__start_svc_data" end_symbol="__stop_svc_data" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_dynamic_data"  inputsections="*(SORT(.log_dynamic_data*))" runin=".log_dynamic_data_run"/>
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_filter_data"  inputsections="*(SORT(.log_filter_data*))" runin=".log_filter_data_run"/>
        <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" runin=".tdata_run" name=".tdata" />
      </MemorySegment>
      <MemorySegment name="RAM" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">
        <ProgramSection load="no" name=".reserved_ram" start="$(RAM_PH_START)" size="$(RAM_START)-$(RAM_PH_START)" />
        <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START)" address_symbol="__app_ram_start__"/>
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run" address_symbol="__start_nrf_sections_run" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".cli_sorted_cmd_ptrs_run" address_symbol="__start_cli_sorted_cmd_ptrs" end_symbol="__stop_cli_sorted_cmd_ptrs" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".log_dynamic_data_run" address_symbol="__start_log_dynamic_data" end_symbol="__stop_log_dynamic_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".log_filter_data_run" address_symbol="__start_log_filter_data" end_symbol="__stop_log_filter_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run_end" address_symbol="__end_nrf_sections_run" />
        <ProgramSection alignment="4" load="No" name=".fast_run" />
        <ProgramSection alignment="4" load="No" name=".data_run" />
        <ProgramSection alignment="4" load="No" name=".tdata_run" />
        <ProgramSection alignment="4" load="No" name=".bss" />
        <ProgramSection alignment="4" load="No" name=".tbss" />
        <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"  address_symbol="__StackLimit" end_symbol="__StackTop"/>
        <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
      </MemorySegment>
      <MemorySegment name="bootloader_settings_page" start="0x000FF000" size="0x1000">
        <ProgramSection alignment="4" keep="Yes" load="No" name=".bootloader_settings_page" address_symbol="__start_bootloader_settings_page" end_symbol="__stop_bootloader_settings_page" start = "0x000FF000" size="0x1000" />
      </MemorySegment>
      <MemorySegment name="mbr_params_page" start="0x000FE000" size="0x1000">
        <ProgramSection alignment="4" keep="Yes" load="No" name=".mbr_params_page" address_symbol="__start_mbr_params_page" end_symbol="__stop_mbr_params_page" start = "0x000FE000" size="0x1000" />
      </MemorySegment>
      <MemorySegment name="uicr_bootloader_start_address" start="0x10001014" size="0x4">
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_bootloader_start_address" address_symbol="__start_uicr_bootloader_start_address" end_symbol="__stop_uicr_bootloader_start_address" start = "0x10001014" size="0x4" />
      </MemorySegment>
      <MemorySegment name="uicr_mbr_params_page" start="0x10001018" size="0x4">
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_mbr_params_page" address_symbol="__start_uicr_mbr_params_page" end_symbol="__stop_uicr_mbr_params_page" start = "0x10001018" size="0x4" />
      </MemorySegment>
    </Root>

    I guess this is why I am getting the error from nrfjprog: The area to write is not erased. It's overlapping with last 4 sections. Kindly help me with that!

  • Yes, if you are reserving the bootloader setting in your application you will see that error of overlapping. But by default there isn't any data should be put into that setting page in compile time. So the area should not be included in the hex file. Please check the bootloader hex file (you can use nrf Connect programmer tool to check). Only after you flash the bootloader and after the bootloader run, then the bootloader setting will be written. If you simply combine the hexes, or don't let the bootloader to run, the bootloader setting is remains blank. 


    You are trying to do something a little bit more advanced (integrate DFU into your application). I would suggest you to go step by step. 

    First get familiar with how you can generate bootloader setting (by using nrfutil) and combine it with the application so that it would accept the bootloader  + application + bootloader setting combined. 

    After you get that working, start to implement DFU in your application, but keep checking to avoid that the UICR being erased. 

Reply
  • Yes, if you are reserving the bootloader setting in your application you will see that error of overlapping. But by default there isn't any data should be put into that setting page in compile time. So the area should not be included in the hex file. Please check the bootloader hex file (you can use nrf Connect programmer tool to check). Only after you flash the bootloader and after the bootloader run, then the bootloader setting will be written. If you simply combine the hexes, or don't let the bootloader to run, the bootloader setting is remains blank. 


    You are trying to do something a little bit more advanced (integrate DFU into your application). I would suggest you to go step by step. 

    First get familiar with how you can generate bootloader setting (by using nrfutil) and combine it with the application so that it would accept the bootloader  + application + bootloader setting combined. 

    After you get that working, start to implement DFU in your application, but keep checking to avoid that the UICR being erased. 

Children
No Data
Related