This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to defined Heap section at specific location in internal SRAM and how to access them from your C code?



To All,

I am using development kit DK-LM3S9B96 (Stellaris LM3S9B96 Microcontroller).  Code Composer Studio Version: 4.1.0.02000.

Q.1 Is there a way to specify heap and stack section in the .cmd file at a specific location in internal RAM? If yes how can it be done?

The map file defines following variable.

20017f80   __STACK_END
00004000   __STACK_SIZE
20017f80   __STACK_TOP
00008000   __SYSMEM_SIZE

ARM Optimizing C/C++ Compiler v4.6 User's Guide says followin about the above variable.

6.1.2 C/C++ System Stack
The C/C++ compiler uses a stack to:
• Allocate local variables
• Pass arguments to functions
• Save register contents
The run-time stack grows from the high addresses to the low addresses. The compiler uses the R13
register to manage this stack. R13 is the stack pointer (SP), which points to the next unused location on
the stack.
The linker sets the stack size, creates a global symbol, __STACK_SIZE, and assigns it a value equal to
the stack size in bytes. The default stack size is 2048 bytes. You can change the stack size at link time by
using the --stack_size option with the linker command. For more information on the --stack_size option,
see Section 4.2.


6.1.3 Dynamic Memory Allocation
The run-time-support library supplied with the ARM compiler contains several functions (such as malloc,
calloc, and realloc) that allow you to allocate memory dynamically for variables at run time.
Memory is allocated from a global pool, or heap, that is defined in the .sysmem section. You can set the
size of the .sysmem section by using the --heap_size=size option with the linker command. The linker also
creates a global symbol, __SYSMEM_SIZE, and assigns it a value equal to the size of the heap in bytes.
The default size is 2048 bytes. For more information on the --heap_size option, see Section 4.2.

Q.2 Can the global variables  __STACK_END,   __STACK_SIZE,    __STACK_TOP,  __SYSMEM_SIZE created and listed in load map, be access within the C coe or in assembly language? If yes, how this can be done?

Q.3 Is there a way to create a global variable similar to __STACK_TOP and __STACK_END for start of heap and end of heap?

Q.4 Is heap storage area is part of .sysmem or .bss?

The stack is clearly specified in the .map file as follows.

20013f80 20013f80 00004000 00000000 rw- .stack

60000000 60000000 0001c8d0 0001c8d0 r-x

I don't see the same thing for heap.

See below part of the load map.

******************************************************************************

TMS470 Linker PC v4.6.1

******************************************************************************

>> Linked Mon Jul 19 20:24:30 2010

OUTPUT FILE NAME: <Beta.out>

ENTRY POINT SYMBOL: "_c_int00" address: 60015d71

 

MEMORY CONFIGURATION

name origin length used unused attr fill

---------------------- -------- --------- -------- -------- ---- --------

FLASH 00000000 00040000 00000000 00040000 R X

SRAM 20000120 00017e60 00012275 00005beb RW X

XSRAM 60000000 00100000 0001c8cc 000e3734 RW X

 

SEGMENT ALLOCATION MAP

run origin load origin length init length attrs members

---------- ----------- ---------- ----------- ----- -------

20000120 20000120 00008000 00000000 rw-

20000120 20000120 00008000 00000000 rw- .sysmem

20008400 20008400 00005c00 00000000 rw-

20008400 20008400 00005c00 00000000 rw- .bss

2000e000 2000e000 00000675 00000675 rw-

2000e000 2000e000 00000675 00000675 rw- .data

20013f80 20013f80 00004000 00000000 rw-

20013f80 20013f80 00004000 00000000 rw- .stack

60000000 60000000 0001c8d0 0001c8d0 r-x

60000000 60000000 00000120 00000120 r-- .intvecs

60000120 60000120 00016cda 00016cda r-x .text

60016dfc 60016dfc 0000581a 0000581a r-- .const

6001c618 6001c618 000002b8 000002b8 r-- .cinit

Q.5 How can I find out which section the heap defined looking at tthe map file?

Any help on this will be very much appereciated.

Thanks in advance for assistacne.

Al Modi

 

  • Ashok,

    Ashok Modi said:

    Q.1 Is there a way to specify heap and stack section in the .cmd file at a specific location in internal RAM? If yes how can it be done?

    As mentioned in the C/C++ Compiler User's guide, the heap and stack are allocated in the memory sections .sysmem and .stack respectively, therefore you can assign these to the desired memory segments. Something similar to:

    MEMORY
    {
    ...
       FAST_HEAP_MEM: origin = 0x20000120 length = 0x00008000
       FAST_STK_MEM:  origin = 0x20008120 length = 0x00004000
    ...
    }

    SECTIONS
    {
    ...
       .sysmem > FAST_HEAP_MEM
       .stack  > FAST_STK_MEM
    ...
    }

    Ashok Modi said:

    Q.2 Can the global variables  __STACK_END,   __STACK_SIZE,    __STACK_TOP,  __SYSMEM_SIZE created and listed in load map, be access within the C coe or in assembly language? If yes, how this can be done?

    Since these are global symbols, I don't see problems in referencing them in both C or assembly source code:

    In C: extern void* _SYSMEM_SIZE; (single underscore)

    In assembly:.ref __SYSMEM_SIZE (double underscore)

    Not sure if there are other implications, though.

    Ashok Modi said:

    Q.3 Is there a way to create a global variable similar to __STACK_TOP and __STACK_END for start of heap and end of heap?

    In theory yes. By knowing the location of the heap in memory you can arbitrarily assign values to pointers there. But as far as I know there is no built-in mechanism in the tools that automatically generates those variables.

    Ashok Modi said:

    Q.4 Is heap storage area is part of .sysmem or .bss?

    See answer to Q.1.

    Ashok Modi said:

    Q.5 How can I find out which section the heap defined looking at tthe map file?

    See answer to Q.1. 

    Hope this helps,

    Rafael 

     

  • desouza said:

    Since these are global symbols, I don't see problems in referencing them in both C or assembly source code:

    In C: extern void* _SYSMEM_SIZE; (single underscore)

    In assembly:.ref __SYSMEM_SIZE (double underscore)

    Not sure if there are other implications, though.

    You have to be a little tricky to access these values in C code.  An unadorned identifier in C code refers to the contents of an object, but in the linker command file, it represents the address of an object. 

    When the linker creates a symbol that really represents an address, such as __STACK_END, if you just declare it as a non-pointer in C code, you get an object which lives at the end of the stack; simply using this symbol unadorned will give you a garbage value.  The address of this object is equal to the value the linker assigned to __STACK_END, so most likely you will always want to take the address of it:

    extern unsigned char _STACK_END; /* Probably contains garbage. */

    #define STACK_END_ADDRESS  (&_STACK_END)

    When the linker creates a symbol that is just a plain number and not an address, such as __STACK_SIZE, there is no C-accessible object, but you still need to take the address of the linker-generated symbol, and you'll also need to cast it to an integer type:

    extern unsigned char _STACK_SIZE; /* Fake object; no storage for this is allocated anywhere.  Its type does not matter. */

    #define STACK_SIZE ((unsigned)&_STACK_SIZE)

  • Thanks for the responses above. The purpose of the above question is to ensure that the STACK and Heap is located always at addres desired. The purpose of tit oaccess from the code is to fille both the stack and heap memory region with some constant data byte value and than either from CCS debug environment or in real code environment see how much stack and heap region is used. Above response indicates how to access them from the C or assembler code.

    Q. Can the heap and stack area be filled with known value in our aplication before it starts using it? 

    Q. Can the heap and stack area be filed with a constant value by using some type of linker option?

    By filling with aknown data value can allow to determine the real usage for both stack and heap and thus can allow optimizing the size of stack and heap.

    Thanks for your assitance in this.

    Al Modi 

  • Ashok,

    Yes, there are options for the MEMORY and SECTIONS directives to fill memory with arbitrary values. Check sections 7.7.2 and 7.8.1 of the ARM Assembly language tools User's Guide (SPNU118H).

    Just for reference for other users, the thread below discusses techniques to monitor the heap usage (you are probably aware of this since you originated it):

    http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/p/51831/183235.aspx#183235

    Archaeologist,

    Thanks for the clarification!

    Cheers,

    Rafael

     

  • To All,

    The linker switch for my project are as follows:

    -z -m"Alpha.map" --stack_size=0x1000 --heap_size=0x4000 --warn_sections -i"C:/Program Files/Texas Instruments/ccsv4/tools/compiler/tms470/lib" -i"C:/Program Files/Texas Instruments/ccsv4/tools/compiler/tms470/include" --reread_libs --rom_model. Attached zip file contains the .cmd file the .map file snape showing the stack and heap setting for my project.

    Q.1 Do some one know why the .sysmem is not there in the .map file? I expected some thing like this on the alpha.map file.

    20000120 20000120 00008000 00000000 rw- .sysmem

    I also do not see the global variable __SYSMEM_SIZE with size of 0x4000 in tha Alpha.map file. I see __STACK_END,    __STACK_SIZE,  __STACK_TOP but no __SYSMEM_SIZE.

    Q.2 Does any one know why?

    With similar settings with other project. I have seen the .sysmem section and __SYSMEM_SIZE. The assembeler manual says the heap should be in .sysmem section and global variable __SYSMEM_SIZE should provide the heap size.

    Any help on this will be appereciated. Thank you.

    Al Modi

  • Sorry forgot to attach the files. Here they are. Thanks.

    Al Modi

    072210.zip
  • I am not seing .sysmem section in the .map file even though the heap size is defined as 0x4000,  is this because the application build does not uses in C run time library function malloc etc. ?

    Q What is the content of libary  "rtsv7M3_T_le_eabi.lib"? Is the library rtsv7M3_T_le_eabi.lib suports all the C run time function?

    Thanks.

    Al Modi

     

  • I found my answer the .sysmem section only gets geenrated in the .map file, if you use any memory function in your application. Even though I had allocated heap size of 0x4000, none of the memory functions were used and hence the .map file did not generated the .sysmem section. I added following simple code and than it did created the .sysmem section.

    Added following code.

     

    string = malloc( 256 );

     

    free( string );

    The map showed following.

    .sysmem 0 20012fc0 00004000 UNINITIALIZED

    20012fc0 00000008 rtsv7M3_T_le_eabi.lib : memory.obj (.sysmem)

    20012fc8 00003ff8 --HOLE--

    00004000 __SYSMEM_SIZE

    Struggled for a while, but finally figured out. Thanks.

    Al Modi