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

Segger Embedded Studio(Crossworks). Write data to UICR.

Hello. I am trying to port bootloader project from SDK to SES. But I do not know how to write data to UICR.

Steps what I've done:

  1. My nRF52832_xAA_MemoryMap.xml looks like (I've added UICR section):
< !DOCTYPE Board_Memory_Definition_File> 
< root name="nRF52832_xxAA">
  < MemorySegment name="FLASH" start="0x00000000" size="0x00080000" access="ReadOnly" />
  < MemorySegment name="UICR" start="0x10001000" size="0x0000020C" access="ReadOnly" />
  < MemorySegment name="RAM" start="0x20000000" size="0x00010000" access="Read/Write" />
< /root>
  1. To my flash_placement I've added:
< MemorySegment name="$(FLASH_NAME:UICR)">
< ProgramSection alignment="4" size="0x04" load="Yes"  name=".uicrBootStartAddress" start="$(UICR_BOOTLOADER:0x10001014)" />
< ProgramSection alignment="4" size="0x04" load="Yes"  name=".uicrMbrParamsPageAddress" start="$(UICR_MBR_PARAM_PAGE:0x10001018)" />
< /MemorySegment>
  1. At main file I've declared:

volatile uint32_t m_uicr_bootloader_start_address attribute ((section(".uicrBootStartAddress"))) = 0x55555555;

So for now I just want to write 0x55555555 in address UICR_BOOTLOADER:0x10001014

Project compiles without any errors/warning. At map file I have (this is obviously only part of map file):

.uicrBootStartAddress
                0x10001014        0x4
                0x10001014                __uicrBootStartAddress_start__ = .
 *(.uicrBootStartAddress .uicrBootStartAddress.*)
                0x10001018                . = ALIGN (MAX ((__uicrBootStartAddress_start__ + 0x4), .), 0x4)
 *fill*         0x10001014        0x4 
                0x10001018                __uicrBootStartAddress_end__ = (__uicrBootStartAddress_start__ + SIZEOF (.uicrBootStartAddress))
                0x00000004                __uicrBootStartAddress_size__ = SIZEOF (.uicrBootStartAddress)
                0x10001018                __uicrBootStartAddress_load_end__ = __uicrBootStartAddress_end__
                0x00000001                . = ASSERT (((__uicrBootStartAddress_start__ == __uicrBootStartAddress_end__) || ((__uicrBootStartAddress_end__ >= __UICR_segment_start__) && (__uicrBootStartAddress_end__ <= __UICR_segment_end__))), error: .uicrBootStartAddress is too large to fit in UICR memory segment)
                0x10001018                __uicrMbrParamsPageAddress_load_start__ = 0x10001018
So it looks like, that .uicrBootStartAddress is in the right place.

After all this steps it should work, at least I've thought so. But when I erase my PCA10040 and download firmware to board, at address 0x10001014 I see only 0xFFFFFFFF:

C:\Program Files (x86)\Nordic Semiconductor\nrf5x\bin>nrfjprog.exe --memrd 0x10001014

0x10001014: FFFFFFFF |....|

(other firmware data is written to board without any problem - I see not 0xFFFFFFFF data from FLASH_START for bootloader (0x00072000)).

The question is: how to write data to UICR from Segger Embedded Stuido's project? Maybe I've done something wrong (forget something?) at the steps above?

Parents
  • It is looks like that compiler/linker doesn't care about "volatile" var and just remove it from code (all code optimizations set to none).

    So at least at Segger Embedded Studio it is not enough to just declare

    volatile static const uint32_t m_uicr_bootloader_start  __attribute__ ((section(".uicrBootStartAddress"))) = 0x55555555;
    

    To see data at .uicrBootStartAddress section I have to use this m_uicr_bootloader_start variable somethere in code, something like:

    int main(void)
    {
    
    uint32_t onlyForTest = m_uicr_bootloader_start;
    
    ...
    
    }
    

    After downloading this to chip I have at right address my 0x55555555:

    C:\Program Files (x86)\Nordic Semiconductor\nrf5x\bin>nrfjprog.exe --memrd 0x10001014
    0x10001014: 55555555                              |UUUU|
    

    Strange, but I can live with it for now.

  • if that's the case then just add

    keep="Yes" 
    

    in the programsection and the linker script will have the keep option set in it.

Reply Children
No Data
Related