Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SDK GCC linker script placing constants in RAM?

Perusing the GCC linker script supplied as part of SDK v16, I noticed that the .data section is specified as follows:

.data : AT (__etext)
{
    __data_start__ = .;
    *(vtable)
    *(.data*)

    . = ALIGN(4);
    /* preinit data */
    PROVIDE_HIDDEN (__preinit_array_start = .);
    *(.preinit_array)
    PROVIDE_HIDDEN (__preinit_array_end = .);

    . = ALIGN(4);
    /* init data */
    PROVIDE_HIDDEN (__init_array_start = .);
    *(SORT(.init_array.*))
    *(.init_array)
    PROVIDE_HIDDEN (__init_array_end = .);

    . = ALIGN(4);
    /* finit data */
    PROVIDE_HIDDEN (__fini_array_start = .);
    *(SORT(.fini_array.*))
    *(.fini_array)
    PROVIDE_HIDDEN (__fini_array_end = .);

    *(.jcr)
    . = ALIGN(4);
    /* All data end */
    __data_end__ = .;

} > RAM

Why on earth are virtual tables and the libc initialization/finalization arrays (__pre_init_array, __init_array, __fini_array) placed in RAM? 

Let's start with the virtual tables: Vtables are compile-time constants, read-only, and consist entirely of function pointers. They function perfectly well in FLASH. The only reason one might even consider allocating them to RAM is for performance (on some architectures RAM doesn't require as many wait cycles as FLASH). But considering how much more FLASH is available than RAM, I would expect the default placement to be in FLASH.

For the initialization/finalization arrays, these are also compile-time constants, read-only, and consist entirely of function pointers. However, these function pointers are used exactly once, either at boot or if a program ever returns from main(). Thus, there is almost zero performance benefit to placing them to RAM. I would definitely think these belong in FLASH. 

So, this begs the question: is there any rational for why RAM is being squandered to store what are effectively read-only lookup tables?

  • Hi,

    This has been like this for a long time. I suspect this is a consequence of Nordic not using much C++, and therefore never having been in a position where we needed to optimize this. I have asked the team responsible for this to comment, but I do not expect to have more until beginning of January.

    Update: I got feedback from the team responsible for the MDK and according to them there is no strong rationale for placing the vtable in RAM. You should consider it a default that can be changed without any side effects if that fits your application better (typically if it is RAM constrained).

Related