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 Reply Children
  • After adding "static const" still have same problem. As for elf file... actualy, have not read elf files before. As I understand it should has all programm sections/segments in it. My elf file looks like 99% binary data and couple of strings including my ".uicrBootStartAddress".

  • SES should have a viewer for ELF files if you double click on it, see if there's anything in the file at the address you used.

    I just looked at one of my Crossworks (basically the same product) projects which has a UICR section, in fact it's just a UICR project and nothing else, I have this

    const struct
    {
    	uint8_t	MAC_ADDRESS[6];
    	char		PIN[6];
    	uint32_t	RESET_CODE;
    } RELAY_DATA  __attribute((section("uicr")))  = {
    	.MAC_ADDRESS = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
    	.PIN         = { '0', 0', '0', '0', '0', '0' },
    	.RESET_CODE  = 0x12345678,
    };
    

    The name of the section in the flash_placement file should be "UICR", not $(FLASH_NAME:UICR). That uses the value of FLASH_NAME if it exists and 'UICR' if it doesn't. Using just UICR is better, although I don't think that's your problem.

  • Elf file at the end has 0x00079690 - last data to be written to flash, and after that - 0x20002c00 - RAM. So nothing at UICR (0x10001014). I've changed $(FLASH_NAME:UICR) to "UICR", but in elf still no data for UICR address.

  • not much more to suggest at this point. Can't see an error, looks right to me and I have a couple of projects with UICR sections in them which I do that way.

    Only thing left to try, View-> Symbol Browser and use the search to find where that symbol has been put, assuming it's not decided that it isn't used and just removed it .. but I don't recall having to tell it to keep the data explicitly.

  • View->Symbol Browser - I see uicrBootStartAddress symbol. With right address, but in "information" option "Section" set to "none" (section that the symbol is defined in). Is that right to be "none" in that case?

    So, at .map file I have uicrBootStartAddress with the right address, but at elf file there no data at that address. So somehow linker(?) decided remove it.

    Tomorrow I'll think about it again. Thanks anyway, RK!

Related