Heap in EVK1100 SDRAM

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

My program needs lots of dynamic (heap) memory so I had to move it out of the internal RAM and into SDRAM. I made a modified version of the loader script from C:\Cygwin\usr\local\avr32\lib\ldscripts\avr32elf_uc3a0512.x into the project directory as Seneca.lds. I changed the heap specification to:

    __heap_start__ = 0xD0000000;
    __heap_end__ = 0xD2000000;

and added the following to the AVR32/GNU C Linker command:

    -T "c:\avrwork\Seneca\Seneca.lds"

The problem that I ran into is apparently somewhere in the startup code it actually does some sort of initialization of the heap area. Of course since the SDRAM controller isn't running this doesn't work.

I had written a test pattern into the SDRAM after initializing the controller as a simple test but this test pattern caused to malloc to fail after about 360Kbytes. Clearing the beginning of the heap area caused malloc to fail immediately. Setting the first 4096 bytes (I didn't determine how many bytes I had to set) to 0xFF seems to make malloc work all the way up to the end of the heap.

I just thought I would let others know of this trap. Unfortunately I just did this by testing, I have no idea what really should be written into the beginning of the heap. Maybe someone else knows.

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

its in the syscalls.c from newlib
i added it to the project changed it to static allocation

int  __attribute__((weak))
     _init_startup ()
{
  extern void _evba;
  void *handler_table;
  handler_table = (void *)malloc(0x104);
  init_exceptions((void *)&_evba, handler_table);
}

maybe it's better way

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

The heap is used by the initialization of the C runtime environment before the main function.

You should initialize the SDRAM Controller in your own version of the _init_startup function which is called by crt0.S after initialization of .data and .bss sections and before any access to the heap.

It could look like:

void _init_startup(void)
{
  extern void _evba;
  void *handler_table;

  // Switch to external oscillator 0.
  pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);

  // Initialize the SDRAM Controller and the external SDRAM chip.
  sdramc_init(FOSC0);

  // Initialize the exception vector table.
  handler_table = (void *)malloc(0x104);
  init_exceptions((void *)&_evba, handler_table);
}

++
Ben

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

KaiBen wrote:

You should initialize the SDRAM Controller in your own version of the _init_startup function which is called by crt0.S after initialization of .data and .bss sections and before any access to the heap.

That worked great. Thanks.

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

Hi! I have a similar problem. I wanted to use SDRAM for variables allocation. The example contained in framework sucks (it only creates an array inside sdram).
What are the correct steps to allocate a variable in sdram? Have I only to add the _init_startup function in my project? Should I modify other settings (such as compiler)? Thanks!

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

Hi!

The purpose of the SDRAMC example provided by the AVR32 Software Framework is to show how to set up the SDRAMC and EBI hardware with an external SDRAM. It is not a linker guide about how to describe memory regions.

All you have to do to use your external SDRAM is to call the sdramc_init function with the appropriate HSB frequency as argument.

Now, if you want your compiler and linker to be able to automatically use the SDRAM memory area to place C-variables or to allocate memory, then you have to tweak your linker script to inform the linker of this new memory. You have to make a choice as to what will be placed in internal SRAM and what will be placed in external SDRAM. The first post in this thread explains how to do it. For further details, read the following:
http://www.gnu.org/software/binu...

You also have to initialize the system clocks and the SDRAM in a low-level initialization function of the compiler that will be called before any access to variables and heap. For AVR32-GCC, it means adding to your project an _init_startup function similar to the above. For IAR EWAVR32, the name of the function is __low_level_init, with the difference that the latter function is called before the initialization of variables.

It means that, contrary to IAR, GCC will not allow to use C-defined variables in SDRAM, but only heap. It is because GCC will try to initialize or to zero these variables before the SDRAM is initialized. There are two possible workarounds:
- Use hardcoded addresses instead of variables. E.g. `*(U32 *)0xD0000000'.
- Write your own crt0.S which will call _init_startup before initialization of variables.

++
Ben

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

Thanks for the reply! Sorry, but I'm a very beginner with avr32 and I can't understand your explainations very well.
First of all: for my degree thesis I need two BIG vectors to be allocated. So I need automatic variables inside SDRAM.

KaiBen wrote:
Now, if you want your compiler and linker to be able to automatically use the SDRAM memory area to place C-variables or to allocate memory, then you have to tweak your linker script to inform the linker of this new memory. You have to make a choice as to what will be placed in internal SRAM and what will be placed in external SDRAM.

I've took a look at avr32elf_uc3a0512.x file but I don't know how to hack it for my purposes. I have to do a something similar to what explained in the first post but for automatic variables. Can you help me with an example of directives to add?
After having modified it I have only to include this file in my project and add the Linker command: -T "$path$iodz.lds" for making it work, right?

KaiBen wrote:
You also have to initialize the system clocks and the SDRAM in a low-level initialization function of the compiler that will be called before any access to variables and heap. For AVR32-GCC, it means adding to your project an _init_startup function similar to the above. It means that, contrary to IAR, GCC will not allow to use C-defined variables in SDRAM, but only heap. It is because GCC will try to initialize or to zero these variables before the SDRAM is initialized. There are two possible workarounds:
- Use hardcoded addresses instead of variables. E.g. `*(U32 *)0xD0000000'.
- Write your own crt0.S which will call _init_startup before initialization of variables.

I'm using GCC with AVR32Studio. I've take a look at crt0.S file, but I'm lost again. Can you suggest how to modify it?
And then, how can I include the modified file to my project? IS there any flag for the linker?

Sorry for the quantity of questions, but I'm a newbie with AVR and GCC...

Thanks a lot!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void _init_startup(void)
{
  extern void _evba;
  void *handler_table;

  // Switch to external oscillator 0.
  pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);

  // Initialize the SDRAM Controller and the external SDRAM chip.
  sdramc_init(FOSC0);

  // Initialize the exception vector table.
  handler_table = (void *)malloc(0x104);
  init_exceptions((void *)&_evba, handler_table);
}

Hi! I've used this function but it gives me a warning about the function init_exceptions (warning: implicit declaration of function 'init_exceptions')
Where is this function located? How can I add it? Does it is in incompatible with intc.h exceptions?

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

iodz83 wrote:
Hi! I've used this function but it gives me a warning about the function init_exceptions (warning: implicit declaration of function 'init_exceptions')
Where is this function located? How can I add it? Does it is in incompatible with intc.h exceptions?

Hi!

You can try `#include '.

For your large vectors, you don't need to alter crt0.S. Just use your _init_startup (without the `-nostdlib' and `-nostartfiles' linker options) and change the following definitions in a copy of avr32elf_uc3a0512.x (to use with the `-T' linker option):

__heap_start__ = 0xD0000000;
__heap_end__ = 0xD2000000;

You can now allocate SDRAM memory for your large vectors with malloc from your regular C code. Note that all variables and stack will still be located in internal SRAM.

Regards,
Ben

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

Thanks for your reply!

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

Hi , I am also new to the AVR32 stuff. I aam using the GCC compiler, and I have the same problem as stated above. the question is:

Write your own crt0.S which will call _init_startup before initialization of variables.

How?

Do any one have any examples on how to ahieve this?

Thanks

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