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.

CC3200 Heap Size, Stack Size, and maximum code size

Other Parts Discussed in Thread: CC3200, UNIFLASH

Hi,

How to check Heap & Stack overflow?

In CCS version 6.1.2.00015, is it able to see whether the heap and the stack is overflow or not?

when choosing project properties-> CCS Build-> ARM Linker -> Basic Options,

there are places for user to set the heap size and stack size.

I test it by changing them to a larger values or smaller values and then try compile my test program.

But nothing seems to be changed in the Memory Allocation (In CCS, Under Windows-> Show View -> Memory Allocation).

How to Set Maximum Code Size

Is that the maximum code & data memory is 256kB -  bottom 16kB = 240kB?

As default from sample program opened from SDK 1.2.0, the heap size & stack size are:

Heap size = 0x8000; i.e. 32kB

Stack size = 0x800; i.e. 2kB

With these heap size & stack size, how to set the maximum code size for my program?

Can i set something like Code = 146KB & Data = 60kB,

such that Code + Data + Heap + Stack = 240kB?

Is it some like to config in the file cc3200v1p32.cmd :

MEMORY
{

    SRAM_CODE (RWX) : origin = 0x20004000, length = 0x24800
    SRAM_DATA (RWX) : origin = 0x20028800, length = 0x0F000

}

Thanks!

Eric

  • Hi,

    It is hard to say what size of stack and heap you need to use, because it depends on your application. For example if you use TI-RTOS you can check information about your hap in RTOS Object View -> HeapMem -> total Size, largest Free size.

    It it not true that you can't use first 16 kB of RAM. For example this is good place where you can place your stack. For this you need modify linker file. Like this:

    MEMORY
    {
        SRAM_BOOT (RWX) : origin = 0x20000000, length = 0x4000   /* 16 KB */
        SRAM_CODE (RWX) : origin = 0x20004000, length = 0x19000  /* 100 KB */
        SRAM_DATA (RWX) : origin = 0x2001D000, length = 0x23000  /* 140 KB */
    }
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > RAM_BASE
        .init_array : > SRAM_CODE
        .vtable :   > SRAM_CODE
        .text   :   > SRAM_CODE
        .const  :   > SRAM_CODE
        .cinit  :   > SRAM_CODE
        .pinit  :   > SRAM_CODE
        .data   :   > SRAM_BOOT
        .bss    :   > SRAM_DATA
        .sysmem :   > SRAM_DATA
        .stack  :   > SRAM_BOOT(HIGH)
    }

    Also there is more techniques how to save code space - like dynamic loading code (example dynamic_lib_loader) or proper setup RTOS if is used.

    Jan

  • Hi Jan,

    Thanks for your reply.

    - It seems you misunderstand i would like to ask. I know it is application dependent. So is there any method to check whether the values (heap size & stack size) are valid & large enough for program execution.

    - Also, how does this value related to the linker file?


    - RTOS Object View -> HeapMem -> seems don't have the option (total Size, largest Free size). Can you capture a screen for this?

    Thanks!

    Best Regards,
    Eric
  • Hi,

    In time of compiling the compiler/linker cannot determine required size of stack and heap. This need to be determined in runtime. If you are using RTOS this parameters can be supervised by OS. If RTOS is not used, it is little bit complicated because you need check this during debug.

    Linker file ... It say to linker where need to place segments into memory. It haven't nothing to do with stack/heap overflow checking.

    Screenshot of RTOS Object View:

    Jan

  • Hi Jan,

    Since linker/ complier won't know the heap size and stack size at the compiling stage, is it correct to say that the heap and stack region should be reserved manually?

    Is it correct to set the the linker file as the example i mentioned?

    Heap size = 0x8000; i.e. 32kB

    Stack size = 0x800; i.e. 2kB

    Data = 60kB,

    assume i do not use the bottom 16kB memory,

    maximum Code size will be146KB?

    and what we need to notify whether overflow is in how many memory are left in the Memory Allocation window (the grey region as the screen captured).

    Best Regards,

    Eric

  • Hi,

    Since linker/ complier won't know the heap size and stack size at the compiling stage, is it correct to say that the heap and stack region should be reserved manually?

    > Yes that is right. Before compiling you need determine right sizes.

     

    Is it correct to set the the linker file as the example i mentioned?

    Heap size = 0x8000; i.e. 32kB

    Stack size = 0x800; i.e. 2kB

    Data = 60kB,

    assume i do not use the bottom 16kB memory,

    maximum Code size will be146KB?

    > Right.

    and what we need to notify whether overflow is in how many memory are left in the Memory Allocation window (the grey region as the screen captured).

    > No. Do not forget that you heap is already located in SRAM_DATA .bss (if you look into .bss you will see your 32kB heap)

     

    Finally you not have properly set linker file. You have set size only to 176kB (90112B*2) instead 240kB. If you have production version of silicon, you can use all 240kB (and with bottom 16kB all 256kB).

    Update: If you have production silicon, just simple use my linker file above. You will see big difference...


    Jan

  • Thanks Jan,

    Eric, in high level, ignoring the 16KB for now, you have a total of 240KB to allocate to your CODE and DATA (assuming production device).

    As in the SDK examples, you can see that everything is mapped to these two sections.

    So heap and stack for example are under DATA section as expected.

    32KB for heap sounds a lot unless you have many memory allocations and large stack on threads that you are running.

    You will not see any change in the Memory Allocation when changing Heap and Stack via the Linker-->Basic options only if you are uting TIRTOS. In this case, it should be applied via the app.cfg file in ti_rtos_config project.

    Hope it is clearer,

    Shlomi

  • Thanks Jan and Shlomi.

    So, will the following be the correct understanding about the heap & size concept?

    The following coding is extracted from the SDK example - email.

    heap size = 0x8000, i.e. 32kB <-- (H_Size)

    stack size = 0x800, i.e. 2kB <-- (S_Size)

    #define OSI_STACK_SIZE                   (2048)

    typedef struct
    {
        //Queue_Elem _elem;
        P_OSI_SPAWN_ENTRY pEntry;
        void* pValue;
    }tPushButtonMsg;

        lRetVal = osi_MsgQCreate(&g_PBQueue,"PBQueue",sizeof(tPushButtonMsg),10); <-- let's say have 10 message storage size in the queue

        lRetVal = osi_TaskCreate(PushButtonHandler, \
                                (signed char*)"PushButtonHandler", \
                                OSI_STACK_SIZE , NULL, \
                                TASK_PRIORITY+2, &g_PushButtonTask );

        lRetVal = osi_TaskCreate(SimpleEmail, (signed char*)"SimpleEmail", \
                                    OSI_STACK_SIZE, \
                                    NULL, TASK_PRIORITY+1, NULL );

    - Assume the program have 1 Message Queue: its heap size = sizeof(tPushButtonMsg) x 10? <--- (1)

    - and assume the program have a Task PushButtonHandler: the heap size = OSI_STACK_SIZE ? <-- (2)

    - and assume the program have a Task SimpleEmail: the heap size = OSI_STACK_SIZE ? <-- (3)

    - then the total heap size required by the program = (1) + (2) + (3) ? <-- (4)

    - heap size remains = (H_Size) - (4) ?

    - The term "OSI_STACK_SIZE" has nothing to do with the stack size (S_Size)? since two tasks (PushButtonHandler & SimpleEmail) have already occupty 4096 bytes??

    - The stack size (S_Size) only be involved during the executing of the interrupts, storing temporary variables & return address, etc?

    Thanks!

    Eric

  • Hi Shlomi,

    What do you mean by production device? How to determine if the CC3200 is a production device? I am using CC3200's launch pad. Can i use the whole 240kB region? If not, what size can be used?

    For the maximum memory i can use (bottom 16kB not be used), the linker file cc3200v1p32.cmd will be like this?

    MEMORY

    {

       /* Application uses internal RAM for program and data */

       /* SRAM_CODE (RWX) : origin = 0x20004000, length = 0x16000 */ (original)

       /* SRAM_DATA (RWX) : origin = 0x2001A000, length = 0x16000 */ (original)

       SRAM_CODE (RWX) : origin = 0x20004000, length = 0x2D000 <-- (updated to 180kB code size, the maximum code size i can use??)

       SRAM_DATA (RWX) : origin = 0x20031000, length = 0xF000 <-- (updated to 60kB data size, what my variable memory can use during my further coding will be 60kB minus 32kB heap & 2kB Stack = 26kB????)

    }

    Thanks!

    Eric

  • Hello Eric,

    By pre-production device I mean devices that are labeled as CC3200HZ/CC3200JZ. Production devices usually ends up with R, stating ROM. It is easy to detect it with Uniflash since it reads out the version from the device and print it out (should see 1.33 and not 1.32 on the console).

    Production devices simmply have less RAM space for code and data. It has 176KB instead or 240KB. BUT, pre-production devices are not compatible with latest SDK and service pack anyway so if you have one of those, kindly replace them.

    cc3200v1p32.cmd linker file as its name indicates would allocate sections to 176KB and not 240KB.

    So, you can divide it as you suggested to make use of all 240KB space and it is up to you how you want to divide it between code and data (as long as it fits).

    Regards,

    Shlomi

  • Hello Eric,

    Specifically, the email example is based on TIRTOS the stack and heap should be defined under app.cfg file in ti_rtos_config project.

    Regardless, each task grabs the size of the stack size from the heap. All variables that dynamically allocate memory are also counted as heap.

    The system stack is as you mentioned, used for system activities and not per task activities.

    Regards,

    Shlomi

  • Hi Shlomi,

    The following is the console output about the device info by uniflash:

    [08:52:46] INFO: reading version info
    [08:52:46] INFO: DEVICE CC3200 ES1.33

    So i think i can allocate maximum size upto 240kB.

    Can you elaborate more on how to set the heap/stack/maximum code size in ccs? Since i got quite confused  about how to handle them correctly in cc3200v1p32.cmd & app.cfg.

    - cc3200v1p32.cmd: This file is automatically generated by ccs. Do i need to add another file that is able to support 240kB? or just simply modify inside the file?

    - app.cfg: where can i handle heap & stack setting?

    Thanks!

    Best Regards,

    Eric

  • Hello Eric,

    You have a production device as expected so you can use the entire 240KB RAM.

    You can use the cmd file itself and edit it or exluse it from your build (by right clicking the project and choose "exclude from build") and adding another cmd file.

    For TIRTOS, you need to use the cmd file and define the boundries between CODE and DATA sections according to your application.

    In app.cfg file, heap is defined by Program.heap = 0x8000 (for example) and system stack by Program.stack = 0x2000;

    You should see these values when choosing View->Memory allocation.

    Regards,

    Shlomi

  • Hi Shlomi,


    Inside CCS, there are two places to set the heap size and stack size. I got confused about the difference between them:

    (Config 1) Inside the imported library "ti_rtos_config"  -> app.cfg -> at "cfg Script":

    /*
     * The BIOS module will create the default heap for the system.
     * Specify the size of this default heap.
     */
    //BIOS.heapSize = 0x8000;
    Program.heap = 0x8000

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x2000;

    (Config 2) under my project (suppose my project is "email" imported from SDK1.2.0) -> properties-> CCS Build -> ARM Linker -> Basic Options:

    Heap size = 0x8000

    Stack size = 0x800

    Will the correct usage be:

    - when using TI_RTOS, only need to config (Config 1), and ignore (Config 2) ?

    - when using Free_RTOS, only need to config (Config 2), and ignore (Config 1)?

    - when using Non-OS, only need to config (Config 2), and ignore (Config 1)?

    Thanks a lot!

    Best Regards,

    Eric

  • Hi Shlomi,

    Since the email example is TI_RTOS. I would like to try using Free_RTOS. How to change to Free_RTOS?

    Best Regards,
    Eric
  • Hello Eric,

    Yes, yes and yes.

    Your answers are correct.

    Regards,

    Shlomi

  • Hello Eric,

    You can look for a reference example that uses FreeRTOS.

    Just look for USE_FREERTOS in the predefined symbols.

    Out of box example is such.

    Regards,

    Shlomi

  • Hello,

    Any update on the post?

    Regards,
    Shlomi

  • When compiling related libraries (oslib) for "out of box" example using FreeRTOS,  the following compile warnings occurred:

    1) function "portCLZ" declared implicitly
    2) function "prvPortStartFirstTask" declared implicitly
    3) Referenced project 'ti_rtos_config' does not exist in the workspace. Project 'oslib' may not build as expected.

    and when i compile "out of box", there is no any errors or warnings. So will the above warnings have any negative effect on the project? Should i need to include 'ti_rtos_config' in the project?

    Best Regards,

    Eric

  • Hello Eric,

    Regarding the first two warnings, these are harmless.

    The implementation resides under .\third_party\FreeRTOS\source\portable\CCS\ARM_CM3\portasm.asm assembly file.

    The 3rd one can happen if you move to tirtos but you do not have ti_rtos_config in the workspace.

    You need to import it as well and recompile.

    Regards,

    Shlomi