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

How to read FLASH_START address of bootloader in application


my setup is sdk 15.3, nrf52840, s140, open bootloader and an application.

Everything is merged, flashed and running and no changes are made at the standard addresses.

In the Memory layout nRF52840 (S140 v6.1.x) the bootloader address range is 0x000F 8000 - 0x000F E000 ?

In the project settings of the example open_bootloader the flash_start address is 0x000e0000 and this i want to read from inside application.

How can i read and store this in a variable ?

Thanks in advance for any hint....


  • See the file app_util.h for a list of defines which could contain what you want.

    An example of use can be found in nrf_bootloader_info.h which again is used in nrf_bootloader_info.c

    #elif defined ( __CC_ARM )
    extern char Load$$LR$$LR_IROM1$$Base;
    extern char Load$$LR$$LR_IROM1$$Length;
    extern char Load$$LR$$LR_IROM1$$Limit;
    #define CODE_START ((uint32_t)&Load$$LR$$LR_IROM1$$Base)
    #define CODE_END   ((uint32_t)&Load$$LR$$LR_IROM1$$Limit)
    #define CODE_SIZE  ((uint32_t)&Load$$LR$$LR_IROM1$$Length)
    #elif defined ( __ICCARM__ )
    extern void * __vector_table;
    extern char RO_END$$Base;
    #define CODE_START ((uint32_t)&__vector_table)
    #define CODE_END   ((uint32_t)&RO_END$$Base)
    #elif defined(__SES_ARM)
    extern uint32_t * _vectors;
    extern uint32_t __FLASH_segment_used_end__;
    #define CODE_START ((uint32_t)&_vectors)
    #define CODE_END   ((uint32_t)&__FLASH_segment_used_end__)
    #elif defined ( __GNUC__ )
    extern uint32_t __isr_vector;
    extern uint32_t __etext;
    #define CODE_START ((uint32_t)&__isr_vector)
    #define CODE_END   ((uint32_t)&__etext)


  • Hello

    thank you for the quick response but at this address / definition


    is the start address of the application


    And i need the start of the bootloader....

    open_bootloader the flash_start address is 0x000e0000
  • Then I would write it to a UICR register (as is done in nrf_bootloader_info.c) and read that value from the application. AFAIK this is exactly the way it is done in the regular bootloader.

    #if defined (__CC_ARM )
        #pragma push
        #pragma diag_suppress 1296
        uint32_t  m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOTLOADER_START_ADDRESS)))
                                                        = BOOTLOADER_START_ADDR;
        #pragma pop
    #elif defined ( __GNUC__ ) || defined ( __SES_ARM )
        volatile uint32_t m_uicr_bootloader_start_address  __attribute__ ((section(".uicr_bootloader_start_address")))
                                                = BOOTLOADER_START_ADDR;
    #elif defined ( __ICCARM__ )
        __root    const uint32_t m_uicr_bootloader_start_address @ NRF_UICR_BOOTLOADER_START_ADDRESS
                                                = BOOTLOADER_START_ADDR;

    In the fds module, they check the value of this UICR register to decide whether or not the bootloader is active. (or at least how it was done previously ((they use MBR now))

    #define BOOTLOADER_ADDRESS      (NRF_UICR->NRFFW[0]) /**< Check UICR, just in case. */
    #define MBR_PARAMS_PAGE_ADDRESS (NRF_UICR->NRFFW[1]) /**< Check UICR, just in case. */

    static uint32_t flash_end_addr(void)
        uint32_t const bootloader_addr = BOOTLOADER_ADDRESS;
        uint32_t const page_sz         = NRF_FICR->CODEPAGESIZE;
    #if defined(NRF52810_XXAA) || defined(NRF52811_XXAA)
        // Hardcode the number of flash pages, necessary for SoC emulation.
        // nRF52810 on nRF52832 and
        // nRF52811 on nRF52840
        uint32_t const code_sz = 48;
       uint32_t const code_sz = NRF_FICR->CODESIZE;
        uint32_t end_addr = (bootloader_addr != 0xFFFFFFFF) ? bootloader_addr : (code_sz * page_sz);
        return end_addr - (FDS_PHY_PAGES_RESERVED * FDS_PHY_PAGE_SIZE * sizeof(uint32_t));

  • They are empty...


    I'm testing this with the regular open_bootloader example without changes.

    How can i write the address to the uicr ?

  • By default MBR is used in SDK 15.3, and not UICR. (i.e. the bootloader addr is stored in 0xFF8 (MBR_BOOTLOADER_ADDR))

    Check the file app_util.c in SDK_folder\components\libraries\util


    #define BOOTLOADER_ADDRESS      ((*(uint32_t *)MBR_BOOTLOADER_ADDR) == 0xFFFFFFFF ? *MBR_UICR_BOOTLOADER_ADDR : *(uint32_t *)MBR_BOOTLOADER_ADDR) /**< The currently configured start address of the bootloader. If 0xFFFFFFFF, no bootloader start address is configured. */

  • I missed that definition.

    Thank you thats exactly what i wanted.

Reply Children
No Data