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

Hello

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....

twittich

  • 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)
    #define CODE_SIZE  (CODE_END - CODE_START)
    
    #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__)
    #define CODE_SIZE  (CODE_END - CODE_START)
    
    #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)
    #define CODE_SIZE  (CODE_END - CODE_START)
    #endif


    #define BOOTLOADER_START_ADDR (CODE_START)

  • Hello

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

    #define BOOTLOADER_START_ADDR (CODE_START)

    is the start address of the application

    0x26000

    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;
    #endif


    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;
    #else
       uint32_t const code_sz = NRF_FICR->CODESIZE;
    #endif
    
        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...

    NRF_UICR->NRFFW[0]=FFFFFFFF
    NRF_UICR->NRFFW[1]=FFFFFFFF

    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

    Snippet:

    #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. */

Related