Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

how to reserve memory segment using SES

Hello,

I have modified flash_placement.xml to define a 64 byte RAM region to be used to preserve data across soft resets. It compiles and links but the memory seems to be set to zeros on reset initialization.

This is part of flash_placement.xml. (I have tried load="No" as well)

    <ProgramSection alignment="4" load="No" name=".tbss" />
    <ProgramSection alignment="4" load="No" name=".non_init" />
    <ProgramSection alignment="8" keep="Yes" size="$(EWAVE_DATA_SIZE)" load="Yes" name=".ewave"/>
    <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" />

This is the map file output:

                0x0000000020007128                __ewave_load_start__ = ALIGN (__non_init_end__, 0x8)

.ewave          0x0000000020007128       0x40
                0x0000000020007128                __ewave_start__ = .
 *(.ewave .ewave.*)
                0x0000000020007168                . = ALIGN (MAX ((__ewave_start__ + 0x40), .), 0x8)
 *fill*         0x0000000020007128       0x40
                0x0000000020007168                __ewave_end__ = (__ewave_start__ + SIZEOF (.ewave))
                0x0000000000000040                __ewave_size__ = SIZEOF (.ewave)
                0x0000000020007168                __ewave_load_end__ = __ewave_end__
                0x0000000000000001                . = ASSERT (((__ewave_start__ == __ewave_end__) || ((__ewave_end__ - __RAM1_segment_start__) <= __RAM1_segment_size__)), error: .ewave is too large to fit

It appears it is defined to be *filled* and I don't know how to disable that.

TIA

  • I also tried making this a separate memory segment.

      <MemorySegment name="RAM2" start="$(RAM_PH_START)+$(RAM_PH_SIZE)-$(EWAVE_DATA_SIZE)" size="$(EWAVE_DATA_SIZE)">
        <ProgramSection load="no" size="$(EWAVE_DATA_SIZE)" name=".ewave" />
      </MemorySegment>

    The memory gets trashed with a J-Link reset or calling NVIC_SystemReset().

    The objective is to store a 32-bit value across resets. The general retention registers are only 8-bits. Is there any other registers that could be used?

  • Hello,

    I'm not seeing any problems with the way you have defined your linker section.  Did you by any chance have a bootloader present when testing this? In that case, maybe the bootloader is overwriting your section after reset?

    It appears it is defined to be *filled* and I don't know how to disable that.

    *Fill* is the unused part of your section, but it does not actually fill any data unless you also modify the startup file (thumb_crt0.s) to do so. And it will go away if you don't specify a fixed  "size" for the section in your flash_placement.xml.

    This is the code I used to test here:

    #define MAGIC_WORD    0x51B1E5DB
    
    typedef struct 
    {
        uint32_t magic_word;
        uint32_t value;
    } boot_count_t;
    
    
    __attribute__((section(".ewave"))) static boot_count_t boot_count;
    
    
    /**@brief Application main function.
     */
     
    int main(void)
    {
        bool erase_bonds;
    
        log_init();
    
        if (boot_count.magic_word != MAGIC_WORD)
        {
          boot_count.magic_word = MAGIC_WORD;
          boot_count.value = 0x0;
        }
        else
        {
            boot_count.value++;
            NRF_LOG_INFO("Boot count: %d", boot_count.value);
            NRF_LOG_PROCESS();
        }
        
        nrf_delay_ms(100);
        /* Reboot */
        NVIC_SystemReset();
    

    and flash_placement:

    Best regards,

    Vidar

  • Hello Vidar,

    I tried your exact solution below and it does not work for me. The RAM is messed up with each reset. This is my configuration.

    • nRF52832
    • SDK 17.0.1
    • Soft device 17.2.0
    • standard bootloader

    It is possible to use the control registers for an unused peripheral? What about all the "reserved" areas?

    Thanks

  • Hello,

    I think the only explanation then is that your bootloader must have a section that overlaps with your ".ewave" section in your app. Did you try without the bootloader?

    Peripheral registers are generally reset to 0x0 on reset. Exception is those that are marked as retained. Still, I can't think of any registers that could be used for this purpose.

    Edit: a solution may be to define the ".ewave" section  in your bootloader and application, and then make sure they both start at the same RAM address.

  • We are using custom hardware. Will try this again using a DK board. It is the standard bootloader. Should be fine.

Related