Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.arch.embedded > #31015
| From | pozz <pozzugno@gmail.com> |
|---|---|
| Newsgroups | comp.arch.embedded |
| Subject | Re: gcc ld and bss sections on SDRAM |
| Date | 2022-03-18 11:49 +0100 |
| Organization | A noiseless patient Spider |
| Message-ID | <t11o4m$js4$1@dont-email.me> (permalink) |
| References | <t11duu$b0l$1@dont-email.me> <t11m3g$ect$1@dont-email.me> |
Il 18/03/2022 11:15, David Brown ha scritto:
> On 18/03/2022 08:56, pozz wrote:
>> 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?
>
> There are several ways to handle this. You can set up the sdram before
> clearing the bss - I think you'll find a weak function called
> SytemInitHook or similar, that you can override with your own version.
> If you are putting a lot of different stuff into the sdram, this is
> probably the best.
ResetISR() is the first call after a reset.
__attribute__ ((section(".after_vectors")))
void
ResetISR(void) {
//
// Copy the data sections from flash to SRAM.
//
unsigned int LoadAddr, ExeAddr, SectionLen;
unsigned int *SectionTableAddr;
// Load base address of Global Section Table
SectionTableAddr = &__data_section_table;
// Copy the data sections from flash to SRAM.
while (SectionTableAddr < &__data_section_table_end) {
LoadAddr = *SectionTableAddr++;
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
data_init(LoadAddr, ExeAddr, SectionLen);
}
// 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);
}
#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)
SystemInit();
#endif
#if defined (__cplusplus)
//
// Call C++ library initialisation
//
__libc_init_array();
#endif
#if defined (__REDLIB__)
// Call the Redlib library, which in turn calls main()
__main() ;
#else
main();
#endif
//
// main() shouldn't return, but if it does, we'll just enter an
infinite loop
//
while (1) {
;
}
}
There isn't any weak function call, anyway I can add my own.
> You can fiddle with either the linker script or the ResetISR function to
> avoid clearing the sdram bss (and copying the sdram initialised data)
> during ResetISR, and do it manually after initialising the ram.
Yes, this is another possibility.
You didn't mention NOLOAD (noinit). It seems to me another good approach
for my problem.
> Often, however, it is a good idea /not/ to use sdram for bss or data.
> Use the internal ram (DTC ram if possible, or OCRAM - depending on the
> particular chip) for that. Put your heap in sdram, along with other big
> buffers such as network buffers, FreeRTOS heap, etc. These can all be
> initialised later once the ram is configured. And you can mark any
> large statically allocated arrays or structures with a section attribute
> for a "noinit" section of the sdram.
I have some images saved in a SDCard and I have to show them on the
display in some cases. I have plenty of SDRAM for other purposes
(framebuffer, for example) so I thought, why read images from SDCard
every time I have to show them?
At startup, I copy images from SDCard to SDRAM and later I can access
images directly from SDRAM.
The maximum size of all images is 2MB and I have this free space on SDRAM.
Back to comp.arch.embedded | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
gcc ld and bss sections on SDRAM pozz <pozzugno@gmail.com> - 2022-03-18 08:56 +0100
Re: gcc ld and bss sections on SDRAM David Brown <david.brown@hesbynett.no> - 2022-03-18 11:15 +0100
Re: gcc ld and bss sections on SDRAM pozz <pozzugno@gmail.com> - 2022-03-18 11:49 +0100
Re: gcc ld and bss sections on SDRAM Stefan Reuther <stefan.news@arcor.de> - 2022-03-18 17:57 +0100
Re: gcc ld and bss sections on SDRAM pozz <pozzugno@gmail.com> - 2022-03-19 16:05 +0100
csiph-web