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

Restricted regions in RAM

Hello all, 
I'm  working with construction like: 

__no_init static uint8_t  buffer[BUFFER_SIZE] @ (0x20010000 - BUFFER_SIZE - 16 * sizeof(uint32_t) );

To pass some data between APP and BOOTLOADER. At first I tried to place this buffer to the end of RAM, but after restart content was broken. I've dumped this area and seen that last 3 words in RAM are always FFs. After many attempts I managed to make my app work. I shifted buffer to several words from the end of RAM. I looked in map file and found only my buffer placed in that part of RAM. 
I wonder if any restricted areas present in RAM for nrf52?

best regards,

  • Hi,

     

     

    Based on the syntax, it looks like you are using IAR. Is this correct?

    It is important that this declaration is present in both your application and dfu. I also recommend that you use the volatile and  __root keyword, as IAR can look at this as a unused section.

     

    Some reset sources may reset your RAM, as seen in the POWER chapter of the PS. However, it is more normal that your application clears this in the startup routine rather than the nRF hardware doing it. Regardless, it is recommended to add a CRC to verify the validity of the data.

    Is both the DFU and application compiled with the same compiler? If the DFU is compiled with GCC for instance, then GCC places the .stack section at the top of RAM, thus your data will be overwritten.

     

    I have done this exercise with Keil and GCC, which has a bit of a different syntax and handling of no_init sections, but I tested the same small snippet in IAR.

    The firmware increments a variable before performing a soft-reset, and on boot up it sets the LED state as (var % 4). Seems to work reliably in IAR as well, and it looks like you do not need to manually setup the .no_init section as you'll need to do with Keil and GCC.

    .

    /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
     *
     * The information contained herein is confidential property of Nordic
     * Semiconductor ASA.Terms and conditions of usage are described in detail
     * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
     *
     * Licensees are granted free, non-transferable use of the information. NO
     * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
     * the file.
     *
     */
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    #include "boards.h"
    
    #ifdef __ARMCC__
    /* Keil */
    static uint32_t test __attribute__( ( zero_init) ) __attribute__((at(0x20007000)));
    #endif
    #ifdef __GNUC__
    /* GCC, see the .ld file for more details */ 
    uint32_t test __attribute__((section(".no_init"))) __attribute__((used));
    #endif
    #ifdef __ICCARM__
    /* IAR */
    __root __no_init static volatile uint32_t test @ 0x20007000;
    #endif
    
    int main(void)
    {
        // Configure the LED pins as outputs
        nrf_gpio_range_cfg_output(LED_START, LED_STOP);
        // Clear LEDs on DK, as they are active LOW
        nrf_gpio_pin_set(BSP_LED_0);
        nrf_gpio_pin_set(BSP_LED_1);
        nrf_gpio_pin_set(BSP_LED_2);
        nrf_gpio_pin_set(BSP_LED_3);
        nrf_delay_us(1000*1000);
        
        // Blink LED to verify that variable "test" is not zero.
        if (test > 0)
        {
            uint8_t led_state = test % 4;
            nrf_gpio_pin_toggle(BSP_LED_0 + led_state);               
            nrf_delay_us(100*1000);
        } 
        
        // If desired, change the RAM retention parameters:
        NRF_POWER->RAMON = POWER_RAMON_ONRAM0_RAM0On  << POWER_RAMON_ONRAM0_Pos
                         | POWER_RAMON_ONRAM1_RAM1On  << POWER_RAMON_ONRAM1_Pos
                         | POWER_RAMON_OFFRAM0_RAM0Off  << POWER_RAMON_OFFRAM0_Pos
                         | POWER_RAMON_OFFRAM1_RAM1Off  << POWER_RAMON_OFFRAM1_Pos;
        
        while(1)
        {     
            test++;
            NVIC_SystemReset();
            // Should not end up here, but just in case; hang tight.
            while(1);
        }
    }
    

     

    Best regards,

    Håkon

  • Thanks  Håkon,
    Yes, I use IAR for compiling, it works even without volatile and  __root keywords for me. I aware about possible data corruption and use crc checking. I use same compiler for bootloader but for testing, flashed only SD + APP.
    Can you try with 

    __root __no_init static volatile uint32_t test @ 0x2000FFFC;


    (for 64kB RAM version chip)?
    For my case the memory content is 0xFFFFFFFF permanently for this address.  
    My initial question was about such regions. 

    Best regards,

    Valerii

  • Hi,

     

    No issues with running it at 0x2000FFFC in my fw snippet.

    Are you word-aligning your BUFFER_SIZE? Do you see the same behavior on other devices?

     

    What SDK version are you using?

     

    Kind regards,

    Håkon

     

     

Related