[SOLVED] How to set specific address to Program Section in flash_placement file

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • [SOLVED] How to set specific address to Program Section in flash_placement file

    Hi everyone,

    I am new to this and I need your advice and help. I am using Segger IDE to develop an aplication along with Nordic's SDK. I have to retain the value of one variable and do not be initialized after system reset. In order to achieve this I have to put RAM in retention and also to place my variable into a special program section in order to avoid initialization after reset. Digging around I found that in order to achieve this I have to add this variable into a program section called .non_Init that is under the RAM memory segment inside the flash_placement.xml file. In order to do this I have to declare the variable like this:

    Source Code

    1. static uint32_t my_variable __attribute__((section(".non_init")));
    See also the attachment with program section.

    I am correct so far?

    Nordic provides the API to put RAM in retention. More specifically I can put a particular RAM section in retention instead of the full RAM size (this will decrease my current consuption). However, to put a paticular RAM section in retention I need to know the memory address of my variable (in order to see in what RAM section it is located) and to ensure that it is not changing. How can I find the start address and size of .non_init section?

    Or is there any other approach I can follow? I am a beginner so please keep things simple :)

    Thanks in advance
    Nick
    Images
    • .non_init.png

      57.66 kB, 879×421, viewed 28 times

    The post was edited 1 time, last by Nikosant03 ().

  • Hello Nick,

    Thank you for your inquiry.
    When using the GNU Linker you should see for all sections __start and __stop variables in the map file.
    You can find the .map file in the Output Files folder in the Project Explorer.
    There you should also find __non_init_start__.
    This is a pointer that points to the start of the non_init section.

    To use it in code you first have to declare it:

    C Source Code

    1. extern unsigned long* __non_init_start__;

    and then you can use it e.g. in a printf().

    C Source Code

    1. printf("noninit start is: 0x%x!\n", &__non_init_start__);
    I hope this helps.


    Best regards,
    Nino
    Please read the forum rules before posting: Forum Rules

    Keep in mind, this is not a support forum. Its main purpose is user to user interaction.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Thank you very much Nino, it works perfect!! However I tried the same approach to find the __non_init_end__ address and the __non_init_size__ but the __non_init_size__ = 0x0
    The address range of .non_init section is dynamic? So, I suppose that there aren't any variables stored at .bss? That's why the __non_init_size__ is 0?

    I found that the start address of __non_init_start__ is 0x200006E4. This means that the first variable that I will add to the section .non_Init will have the address 0x200006E4 isn't it?

    Source Code

    1. extern unsigned long* __non_init_start__;
    2. extern unsigned long* __non_init_end__;
    3. extern unsigned long* __non_init_size__;
    4. NRF_LOG_INFO("noninit start is: 0x%x!\n", &__non_init_start__);
    5. NRF_LOG_INFO("noninit end is: 0x%x!\n", &__non_init_end__);
    6. NRF_LOG_INFO("noninit size: 0x%x!\n", &__non_init_size__);

    I found the section on the .map file. Very helpfull thanks!!

    Source Code

    1. *(.non_init .non_init.*)
    2. 0x0000000020004260 __non_init_end__ = (__non_init_start__ + SIZEOF (.non_init))
    3. 0x0000000000000000 __non_init_size__ = SIZEOF (.non_init)
    4. 0x0000000020004260 __non_init_load_end__ = __non_init_end__
    5. 0x0000000000000001 . = ASSERT (((__non_init_start__ == __non_init_end__) || ((__non_init_end__ - __RAM_segment_start__) <= __RAM_segment_size__)), error: .non_init is too large to fit in RAM memory segment)
    6. 0x0000000020004260 __heap_load_start__ = ALIGN (__non_init_end__, 0x4)
  • Hello,

    Did you place anything in the non_init() section?
    I also get size 0 and end = start if the section is empty.
    Once I place something in there it shows the expected values.
    For example:

    C Source Code

    1. extern unsigned long* __non_init_start__;
    2. extern unsigned long* __non_init_end__;
    3. extern unsigned long* __non_init_size__;
    4. volatile int _aArray[256] __attribute__((section(".non_init")));
    5. /*********************************************************************
    6. *
    7. * main()
    8. *
    9. * Function description
    10. * Application entry point.
    11. */
    12. int main(void) {
    13. int i;
    14. printf("noninit start is: 0x%x!\n", &__non_init_start__);
    15. printf("noninit end is: 0x%x!\n", &__non_init_end__);
    16. printf("noninit size is: 0x%x!\n", &__non_init_size__);
    17. for (i = 0; i < 100; i++) {
    18. _aArray[i] = i;
    19. printf("noninit start is: 0x%x!\n", _aArray[i]);
    20. }
    21. do {
    22. i++;
    23. } while (1);
    24. }
    Display All

    Does it work for you as shown in the example?

    Best regards,
    Nino
    Please read the forum rules before posting: Forum Rules

    Keep in mind, this is not a support forum. Its main purpose is user to user interaction.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Nick,

    Great to hear that you are up and running again.
    We will consider this thread as solved now.

    Best regards,
    Nino
    Please read the forum rules before posting: Forum Rules

    Keep in mind, this is not a support forum. Its main purpose is user to user interaction.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.