Skip to main content
TDK
June 20, 2019
Solved

Prevent zero-initialized arrays in CCMRAM from being stored in FLASH.

  • June 20, 2019
  • 4 replies
  • 1988 views

I am using the CCMRAM to store some large array which should be zero-initialized.

My definition for the arrays is similar to:

__attribute__ ((section (".ccmram")))
uint32_t large_array[4096];

Obviously, there is no constructor for these and there should not be a need to store the initial value of this array in flash. However, that is what the linker is doing.

The relevant portion of my linker script is as follows:

CCMRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
 
...
 
 /* uninitialized data in CCMRAM */
 .ccmram :
 {
 . = ALIGN(4);
 _sccmram = .; /* create a global symbol at ccmram start */
 *(.ccmram)
 *(.ccmram*)
 . = ALIGN(4);
 _eccmram = .; /* create a global symbol at ccmram end */
 } >CCMRAM AT >FLASH

How do I get the linker to not store these in flash?

I tried removing the ">FLASH" from the previous line, however the binary file produced grew fro ~200kB to 200MB, which is not desired.

If I move these arrays to RAM and remove the __attribute__ line, it works as desired.

I'm using GNU for ARM compiler/linker targeting an STM32F429ZI.

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    Beyond all the FLASH/RAM nonsense

    .CCMRAM (NOLOAD):

    {

    *(.ccmram)

    *(.ccmram*)

    } > CCM_RAM

    4 replies

    Tesla DeLorean
    Tesla DeLoreanBest answer
    Guru
    June 20, 2019

    Beyond all the FLASH/RAM nonsense

    .CCMRAM (NOLOAD):

    {

    *(.ccmram)

    *(.ccmram*)

    } > CCM_RAM

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    TDK
    TDKAuthor
    June 21, 2019

    Thanks Clive,

    Is there a user manual for the linker somewhere? It seems like the most obtuse piece of software. I I google "gnu arm linker" I get mostly example linker files, and even the user-manualy hits don't have anything about NOLOAD.

    For example, why would NOLOAD be necessary for this in CCMRAM but not for variables in RAM? Everything I know about linker files has been through reverse engineering, which is not the way it should be.

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    Tesla DeLorean
    Guru
    June 21, 2019

    The real problem is that the GNU/GCC tools, and the methods for unpacking the load region(s) are extremely poor. The linker was originally designed for ELF executables in the LINUX sense (EXE/DLL) and not ROMable code that must unpack itself, rather than load into RAM from disk. The code in startup.s does the unpacking, and that involves either a) copying data from ROM/FLASH to RAM, or b) zeroing the statics (BSS). There are a lot of dependencies on order and symbols created by the linker script. On things like Keil this much more elegant as the linker builds tables, and adds functions to unpack.

    The ELF format has NOBITS section type indicating sections of the executable image don't have any file content behind them. These are like NOINIT sections in other tools, and the GNU linker flags them using NOLOAD

    https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/sections.html

    Thinks are compounded if you want binary files, and the memory regions are significantly dispersed through memory, ie some in 0x10000000, and some in 0x20000000. The .HEX files can describe sparse memory, .BIN must describe a massive blob with a large unused space between the two.

    I learned about Assemblers, Linkers and Loaders while I was in High School, and have had to write several over the years, so I have an appreciation of the mechanics, if not the specifics in a given instance.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..