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.

C6748 Not enough memory

Other Parts Discussed in Thread: OMAPL138

Hi,

I am using a C6748 DSP and I don't have enough memory while using my code with a lot of functions.

I have a memory error when using this function to create arrays:

                      char *SngAlloc(int n, size_t sz)
                      {
                                char *c;
                                if ((c = (char *)calloc(n, sz)) == NULL)
                                printf("[SngAlloc] Not enough memory\n");
                                return c;
                       }

and my memory sections are:

SECTIONS
{
 
   .text       > L3_CBA_RAM            ( shared RAM)
   .switch     > L3_CBA_RAM
   .data       > L3_CBA_RAM
   .cinit      > L3_CBA_RAM
   .pinit    > L3_CBA_RAM
   .bss        > L3_CBA_RAM
   .far        > DDR
   .const      > L3_CBA_RAM
   .printf    > L3_CBA_RAM
   .cio        > L3_CBA_RAM
   .sysmem     > L3_CBA_RAM
   .stack      > L3_CBA_RAM
}

I tried to change these sections but still don't work, I don't know where(in which section) calloc variables are created and how can I optimise it. Thank you

  • Nanou,

    The malloc and its derivative functions (calloc included) allocate memory in the heap; therefore you must be sure that:

    - The linker is allocating the proper heap size by either specifying it in the linker command file (by setting the option -heap <desired_size>) or set the heap size in the Project Options.
    - The memory section .sysmem is being placed in a memory segment with enough space.

    These tips should solve this issue.

    Just as a reference, check section 5.4.5 of the C6000 Compiler User's Guide

    Hope this helps,

    Rafael

  • Hi Rafael,

    thank you for your help, I tried what you told me and to have a lot of space I placed the .sysmem in the external memory

    -l rts67plus.lib
    -l ..\lib\evmc6748_bsl.lib

    -stack           0x00001000
    -heap            0x01000000

    MEMORY
    {
       dsp_l2_ram:      ORIGIN = 0x11800000  LENGTH = 0x00040000
       shared_ram:      ORIGIN = 0x80000000  LENGTH = 0x00020000
       external_ram:    ORIGIN = 0xC0000000  LENGTH = 0x20000000
       arm_local_ram:   ORIGIN = 0xFFFF0000  LENGTH = 0x00002000

    }

    SECTIONS
    {
     
       .text       >  shared_ram
       .switch     >  shared_ram
       .data       >  shared_ram
       .cinit      >  shared_ram
       .pinit    >  shared_ram
       .bss        >  shared_ram
       .const      >  shared_ram
       .printf    >  shared_ram
       .cio        >  shared_ram
       .sysmem     >  external_ram
       .stack      >  shared_ram 

    .far        >  external_ram

    }

    And i still have the memory error  printed when I do calloc functions:

    [SngAlloc] Not enough memory
    [SngAlloc] Not enough memory
    [GetRadii_1] Not enough memory

  • Hi Nanou,

    Are you sure that your linker (.cmd) file is getting linked properly? I would suggest that you try to allocate Heap Size via "Project Options" and crosscheck whether the Heap Size has been allocated properly. Because the heap size you are allocating in your linker file is big enough to accommodate the dynamic memory allocated by calloc.

    Regards,

    Sid

     

  • Hi Sid,

    I didn't find the "Project Options" so I went to the  Project ->Build Options->Linker and I change the heap size in the Basic category and still have the memory error, I don't if I did what you said, if not can you explain me what to do step by step please.

    Thank you

  • Nanou,

    You are correct in the step-by-step procedure to add a heap. I am getting the same allocation error in the calloc function, but I still couldn't figure out what may be happening - it may well be an issue with the runtime support libraries or an usage detail we are missing.

    Still checking...

    Rafael

  • Nanou,

    I checked some additional information and filed the bug number SDSCM00035619. As soon as the external database is updated, please check its status at this link.  

    To assist you for the moment I posted a workaround at the bug link (just a malloc followed by a for loop that initializes everything to zero).

    Usually the engineering team is pretty responsive to fix bugs, therefore expect its fix in a future release of the code generation tools (I used 6.1.13 in my tests).

    Hope this helps,

    Rafael

     

  • Hello,

     

    I'm having the same problem, and I can't find the bug in the bug database. Can you post the workaround here in the forum?

     

    Thanks!

  • Nanou, José,

    I can't reproduce the issue here. I overlooked the correct usage of the parameters when I filed the bug.

    What values are you using for "n" and "sz"? The call to calloc() asks for "n" objects of size "sz" (which is "n" times "sz" bytes) and initializes everything to zero. This way it is easy to reach the upper limit of the allocated heap. 

    For example, if you want to allocate 1024 bytes it would be necessary to either do a calloc(4,256), or calloc(1,1024), etc.

    Please feel free to send me the values you are using if you are still seeing this error.

    Best regards,

    Rafael 

  • Hello,

     

    This is a snippet from the code where I get the error:

     

         ....

      unsigned K = sizeof(bsp_sample_t);

      ....
      fs_buffer_tx = (bsp_sample_t *)malloc(params.fs_sig_buffer_len*K*2);
      if(!fs_buffer_tx) return plm_error=OUT_OF_RAM;

      ....

     

    The first call I make to malloc fails. The argument value is 14903104, which is more that I remembered (This code is tested and debugged on a linux host and then ported to the embedded target, and I may have hit some bug there) but less than the available 64MB of external ram. This is my linker command file:

     

     

    /*****************************************************************************
    * linker command file for C6748 test code.
    *
    * © Copyright 2009, Logic Product Development, Inc. All Rights Reserved.
    ******************************************************************************/

    -l rts67plus.lib
    -l ..\..\..\..\bsl\lib\evmc6748_bsl.lib

    -stack           0x00000800
    -heap            0x00e00000

    MEMORY
    {
       dsp_l2_ram:      ORIGIN = 0x11800000  LENGTH = 0x00040000
       shared_ram:      ORIGIN = 0x80000000  LENGTH = 0x00020000
       external_ram:    ORIGIN = 0xC0000000  LENGTH = 0x08000000
       arm_local_ram:   ORIGIN = 0xFFFF0000  LENGTH = 0x00002000
    }

    SECTIONS
    {
       .text       > shared_ram
       .const      > shared_ram
       .bss        > shared_ram
       .far        > external_ram
       .switch     > shared_ram
       .stack      > shared_ram
       .data       > shared_ram
       .cinit      > shared_ram
       .sysmem     > external_ram
       .cio        > shared_ram
    }


    I think I'm spotting an error there because my SOM has 64MB and not 128MB (0x08000000) but otherwise the cmd file looks like one seen earlier in this thread.

    I should add that I started using this board this very morning so you should take anything I say with a grain of salt :)

    I can configure my code not to use dynamic allocation so for me this is not a very urgent issue.

     

    Thank you for your prompt response!

     

     

     

     

  • Hello again,

     

    I have found an error in my CMD file (post above); the heap size was too small. Once I have enlarged the heap, the problem dissapears. My mistake is that my code was using up more memory that I rememmbered, because I'm calling it with different parameters than I used to in earlier versions :)

    I'm sorry I wasted your time...

     

    Thank you!

  • José,

    No need to apologize; I also overlooked things on this issue. :)

    Cheers,

    Rafael

  • Hi,

    Sorry but I still have a problem with my code, as you said last time  the heap size I am allocating is big enough to accommodate the dynamic memory allocated by calloc. Because I am using a lot of malloc function I have increased the heap size again and this time my code crashed. when I move the heap size from 0x0F000000 to 0x10000000, I went to an infinite loop.

    Here are just few  instructions :

     

    ref=(struct Tref**)DblAlloc( 42, 1, sizeof(struct Tref)); // - Ref Initialization

    test =(struct Ttest**)DblAlloc( 42, 1, sizeof(struct Ttest));//- Test Initialization

    U_matrix=(float **)DblAlloc(42, numberofpeak, sizeof(float)); //allocate memory to U_matrix array

    result->f=(float*)calloc(42, sizeof(float));

    result->v=(float*)calloc(42 sizeof(float));

    result->u=(float*)calloc(42, sizeof(float));

     

     And I also have big arrays I don't know if it matters:

     

     

    #pragma DATA_ALIGN(xmit_buffer,8192);

    #pragma DATA_ALIGN(ChA,8192);

    #pragma DATA_ALIGN(ChB,8192);

    #pragma DATA_ALIGN(corr,8192);

    #pragma DATA_ALIGN(fft1,8192);

    #pragma DATA_ALIGN(filter,8192);

    #pragma DATA_ALIGN(ampTable,8192);

     

     

     

    char **DblAlloc( int nrows, int ncols, size_t sz)

    {

    int i,j;

    char **c;

    c = (char **) calloc( nrows, sizeof(char *));

    if ( c==NULL )

    {

    printf("Not enough memory\0");

    return NULL;

    }

    for ( i=0 ; i<nrows ; i++ )

    {

    c[i]=(char *) calloc( ncols, sz);

    if ( c[i]==NULL )

    {

    for ( j=i-1 ; j>=0 ; j--)

    free(c[j]);

    free(c);

    printf("Not enough memory\0");

    return NULL;

    }

    }

    return c;

    }

  • Nanou,

    I ran the DblAlloc() routine you sent in a simulator with no problems. Although you are allocating a huge heap, from the code you sent I can't necessarily tell what is the size of the total required allocation space. What are the values of sizeof(Tref) or sizeof(Ttest)? Which calls to calloc() fail? All of them?

    The reason I am asking this is because I also tested the calloc() function by allocating close to 800MB of chars in the simulator. My exact code is:

    c = (char*) calloc(0x10000, 0x2F00); // 770MB

     

    All memory sections and the heap of size 0x2F800000 are allocated in the external memory.

    This shows that the calloc() can allocate large amounts of code; however, the fact that the processor loses itself during execution with a larger heap may indicate that something is overwriting code. Tomorrow I will try to reproduce this in hardware.

    Cheers,

    Rafael

     

     

     

  • Nanou,

    I managed to test it today on the C6748 EVM and it worked fine. I allocated 0x7000000 on the external memory (almost 120MB of memory) and did not have any problems. I also tested the integrity of the allocation by loading all sections (.text, .cio, .const, etc.) in external memory and I had no problem. I also filled the heap with 0xFF and and after the calloc() call everything was correctly initialized to zero.

    With this I am almost certain the calloc() is not causing the problem.

    I am pretty sure you already know this, but just as a cleanup check:

    - Make sure all the pointers are correctly initialized before using them. Memory overwrite is usually caused by rogue pointers;

    - If using DSP/BIOS, any calls to malloc() and its derivatives will lock the memory segment. If other threads are trying to access the same memory, this can cause missed schedules and potentially a system lock up.

    - The DblAlloc() function creates arrays of allocated sizeof(struct). Make sure you are keeping these array sizes in tight control (I tested the routine and it surely works here);

    Hope this information helps,

    Rafael

  • Thank You rafael,

    I'll try everything you said as soon as possible, now I have something urgent  to do before taking back the DSP.

    Thank you again

  • Nanou,

    I think I hit the issue you are having.

    The C6748 external memory space can access 512MB (0x20000000), but the external memory physically installed on its EVM is 0x8000000 (128MB).

    In my linker command file I limited the external memory segment to the correct installed physical size (EMIFBSDRAM o = 0xC0000000 l = 0x08000000), set the heap to use it completely (-heap 0x8000000) and put all sections (but .sysmem) in internal memory.

    But this morning I modified the linker command file. I set the external memory segment to address the full memory space accessible by the C6748 (EMIFBSDRAM o = 0xC0000000 l = 0x20000000) and moved all sections to external memory. By accident I left the heap the same size as before, meaning it was still using the entire physical installed memory (-heap 0x8000000). 

    In this case I had the same issue you reported. All the heap and the code was loaded to the external memory properly. However, since the heap was already taking all the external memory space from 0xC0000000-0xC7FFFFFF, the code was stored in the address starting at 0xC8000000 (higher than the physically installed memory!). The issue here is that the DSP external memory bus actually caused the memory to wrap around its limit and actually placed the code in 0xC0000000. Once calloc() started execution it was writing zero to all the code sections and making the DSP wander in a sea of NOPs.

    Note that this would be much more difficult to discover if malloc() was being used instead - it would not fail at the function call, but only when the dynamic array was being filled with values!

    Despite this causes a critical failure, it is one of these gaps between hardware and software realms. From a software standpoint there was never an issue, since the misconfigured memory segment caused the linker to pass all allocation checks. From a hardware standpoint, it usually does not have a mechanism that warns about memory boundaries and relies on the software to properly limit these boundaries.

    I send the attached project I used. Download the file and import it directly to your workspace (no need to unzip): go to menu Project --> Import Existing CCS/CCE Eclipse Project --> Select Archive File --> point to the location of <testcase.zip> and click finish.

    Hope this information helps,

    Rafael

     

     

    testcase.zip
  • Thank you Rafael,

    In the CCSv3.3 that I'm using I didn't find the Project --> Import Existing CCS/CCE Eclipse Project --> Select Archive File --> point to the location of <testcase.zip> and click finish. But I've included your  omapl138.cmd file in my project and set the heap to use the external memory completely (-heap 0x8000000) , and unfortunately I still have a memory error but less than before, I think I really need a big memory for all my calloc functions, it is a big project actually. I will check for everything you said in your previous post for the pointers,etc.

    In case I need more memory than what it is installed on this EVM, what can I do?

    Thanks,

    Nanou

  • Nanou,

    Unfortunately I don't know how to add memory to the EVM - everything is located in the SOM module.

    Rafael

  • Hi Rafael,

    I was thinking about using the  Asynchronous EMIF / SDRAM wich size is :

    0x4000 0000 - 0x5FFFFFFF                    512M                            EMIFA SDRAM data (CS0).

    I tried to allocate the sysmem in this section but it didn't, I am wondering if there are some initialisations to do before using this memory, I've never used it before.

    Do you have an idea?

  • Nanou,

    By looking at the EVM comparison page, it seems the only external RAM memory on the development kit is the mDDR. The EMIFA pins are available on the connector J28 and have Flash memory if the UI Board is installed.

    In your case it seems that you will have to design a custom board with additional RAM and plug it to the J28 connector.

    In the meantime I would try to test your current system in smaller parts and try to avoid allocating all the buffers at once.

    Cheers,

    Rafael

  • Rafael,

    the connector J28 is already connected to the UI Board and I'm using the DAC-ADC too on this UI Board, so I already have access to EMIFA pins right?

     

    Nanou

  • Nanou,

    Yes, but the UI board only has Flash memory connected to the EMIFA (not RAM), therefore in practice you will not be able to dynamically allocate anything to it.

    You could design another daughterboard that has the AD/DA and extra RAM instead of Flash, which I think it is a much simpler approach instead of modifying the SOM module and adding a larger DDR... But I don't know all the details and considerations about RAM timings, etc.

    Sorry I can't be of much help in this case.

    Cheers,

    Rafael