My platform is LPC546xx, Cortex-M4 by NXP, and the build environment is based on GCC ARM toolchain (MCUXpresso IDE). However the question is generic.
The default linker script instructs linker to put bss sections (zero initialized data) in internal RAM. During startup, before main, bss sections, described in a table on Flash, are reset to zero:
__attribute__ ((section(".after_vectors.init_bss"))) void bss_init(unsigned int start, unsigned int len) { unsigned int *pulDest = (unsigned int*) start; unsigned int loop; for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = 0; }
extern unsigned int __bss_section_table; extern unsigned int __bss_section_table_end;
void ResetISR(void) { ... // At this point, SectionTableAddr = &__bss_section_table; // Zero fill the bss segment while (SectionTableAddr < &__bss_section_table_end) { ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; bss_init(ExeAddr, SectionLen); }
... main(); ... }
This works well until I add a new RAM memory section on external bus (it is a SDRAM). Suppose I want to allocate a big variable on SDRAM. This can be done in different ways (I use some facilities of MCUXpresso IDE).
Now the startup code is broken, because SDRAM memory can be accessed only after it is configured (during main), but the bss initialization is done before main.
I know I can rewrite ResetISR() or bss_init() to avoid accessing external bus addresses or I can configure SDRAM during ResetISR() before calling bss_init().
I suspect there's a better and more cleaner way. Noinit sections?