Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.arch.embedded > #31015

Re: gcc ld and bss sections on SDRAM

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>

Show all headers | View raw


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


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