.bss in SDRAM issue with heap_3.c

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

 

I'm using Atmel Studio 7 (lwip, FreeRTOS 7) and i'm unsuccessfully trying to allocate .bss into SDRAM, but i am succesfully doing it for the Heap. My actual issue is that heaps_3.c (void *pvPortMalloc( size_t xWantedSize )) is unable to allocate memory (always return 0x0000) when .bss is in SDRAM, by switching back .bss to INTRAM this is fixed.

 

After reading a lot of documentation, is obvious for me (correct me if i'm wrong) that .bss was initialized when SDRAM was not, so i need to initialize SDRAM before that happens. The problem is, I cant find crt0.S anywhere in the project (in program files/toolchain there is a crt0.S, is unclear for me if that's called magically). In my folder ASF I only have trampoline_uc3.S:

 

https://www.screencast.com/t/vDQ...

 

then, i don't know from where _init_startup(void) (is in port.c, a file in freeRTOS) is beign called, and is the earliest function i can see before reaching to main() but i guess is too late by that time. My questions could be resumed in:

 

  • Where can I initialize SDRAM before .bss in this project (based in example LWIP with DHCP /freetos from ATMEL Studio 7)?
  • heaps_3.c (void *pvPortMalloc( size_t xWantedSize )) is unable to allocate memory when .bss is in SDRAM, by switching back .bss to INTRAM this is fixed,
  • where i can find WHO calls int _init_startup(void) for this code? init_startup() is in port.c a file from freeRTOS 7 excecuted before main

 

when it fails i modify the original linker from:

__bss_start = .;
  .bss            :
  {
    *(.dynbss)
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(COMMON)
    /* Align here to ensure that the .bss section occupies space up to
       _end.  Align after .bss to ensure correct alignment even if the
       .bss section disappears because there are no input sections.  */
    . = ALIGN(8);
  } >INTRAM AT>INTRAM:INTRAM

 

 

to 

 

 .bss            :
  {
    *(.dynbss)
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(COMMON)
    /* Align here to ensure that the .bss section occupies space up to
       _end.  Align after .bss to ensure correct alignment even if the
       .bss section disappears because there are no input sections.  */
    . = ALIGN(8);
  } >SDRAM AT>SDRAM :SDRAM

And now heap_3.c fails always when creating the first tasks

 

 

Any help or comment is greatly appreciated, thanks a lot

 

(added the linker, changed the extension only)

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know nothing about UC3 so I don't know if it's done in the same way as AVR8 but I'm sort of assuming AVR8 may have been used as a starting point. If that's the case it may be worth reading about this stuff in the AVR8 manual and see if their are parallels for AVR32...

 

http://www.nongnu.org/avr-libc/u...

http://www.nongnu.org/avr-libc/u...

 

One thing you will learn there is that AVR8 has come code sections defined in the linker script before the main .text section so it's roughly:

.vectors
.init0
.init1
.init2
..
.init8
.init9
.text

The even numbered .init sections are already used by the C runtime so things like stack setting happen in .init0 and the BSS and .data setup don't happen until .init4. So if you want to pre-empt the BSS/.data setup with your own code that "gets in early" you put it in an odd numbered init section (usually init3) with something like:

__attribute__((naked, section(".init3"))) void early(void) {
    // do stuff like setting up ext-mem interfaces
}

Maybe, just maybe AVR32/UC3 has been done in some similar kind of way? (if the .x file mentions lots of .initN then the chances are that is "yes" ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Mr. Clawson, 

(somehow i have problems logging in with my accound)

 

Thank you for your answer, seems AVR32 is not exactly the same but the functionality you described is exactly what i needed.

In any example code that uses freeRTOS for Atmel studio 7.0 seems:

 

  •  the linker calls Trampoline on boot:    -Wl,--relax -T../src/ASF/avr32/utils/linker_scripts/at32uc3a/0512/gcc/link_uc3a0512.lds -Wl,-e,_trampoline
  • and this calls a pre-compiled file in the toolchain crt0.o, specifically an assembler function called _stext
  • What i did is add -nostartfiles (prevents the use of crt0.o) and added a new assambler file startup_uc3.s in order to replace the precompiled function _stext from crt0.s
  • Now trampoline calls _stext that is contained in my startup_uc3 which initializes stack,data, bss. (example startup_uc3.s file used)

 

To clarify how is this done, this is adding a new function in the linker like .mycustomsection, update linker flags to add( -Wl,-e,_start) then in the startup_uc3.s put .section  .mycustomsection, "ax", @progbits (this last one i didn't test it thoroughly)

Linker changes

SECTIONS
{
  
  /* If this heap size is selected, all the INTRAM space from the end of the
     data area to the beginning of the stack will be allocated for the heap. */
  __max_heap_size__ = -1;

  /* Use a default heap size if heap size was not defined. */
  __heap_size__ = DEFINED(__heap_size__) ? __heap_size__ : LENGTH(SDRAM)-0x00400000;

  /* Use a default stack size if stack size was not defined. */
  __stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 4K;

  /* Read-only sections, merged into text segment: */
  PROVIDE (__executable_start = 0x80000000); . = 0x80000000;
  .interp         : { *(.interp) } >FLASH AT>FLASH :FLASH
  .mycustomsection         : { *(.mycustomsection) } >FLASH AT>FLASH :FLASH
  .reset		  :	{ KEEP(*(.reset)) } >FLASH AT>FLASH :FLASH
  .hash           : { *(.hash) } >FLASH AT>FLASH :FLASH
  .dynsym         : { *(.dynsym) } >FLASH AT>FLASH :FLASH

C file:

 

#include <avr32/io.h>


//! @{
//! \verbatim


  // This must be linked @ 0x80000000 if it is to be run upon reset.
  .section  .mycustomsection, "ax", @progbits


  .global _start
  .global _early
  .type _start, @function
  .type _early, @function
_start:
  // Jump to the C runtime startup routine.

So in _start you could put a call to any c function like sdram_init() with a call:

.global _sdram_init
 
_start:
lda.w   sp, _estack
call _sdram_init

 

Linker flag on toolchain:

-Wl,--relax -T../src/ASF/avr32/utils/linker_scripts/at32uc3a/0512/gcc/link_uc3a0512.lds -Wl,-e,_start -nostartfiles

 

 

So in my case i just recycled the trampoline function which does something like this. This seems very simple, but i had a lot of troubles finding out, thanks a lot for your help i hope this helps someone else. If i misunderstood any of this, please let me know i just used what it worked for me.

 

 

Thanks a lot