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.

OMAP L138 CMEM/RAM Allocation/Usage

Hi,

I'm running an OMAP L138 board with 64MB RAM and I boot the system from an SD-card. I would like to make use of its RAM, DSP, and other components through HPI and ethernet interface for other systems.
For that purpose I use C6RunLib for an ARM server process to handle requests.

I would like to allocate a small portion (e.g. 8MB) of that 64MB OMAP-RAM for the DSP and the rest (as much as possible) with a fixed size for other systems to use. I have two topics I'm interested in.

 

1.
I don't think I have understood the memory allocation and usage entirely yet. I'm trying to figure out where I have to allocate RAM space to get what I want.
As I understand CMEM reserves 32MB for a (dynamic) heap buffer from the OMAP-RAM. This heap can then be used from the ARM and the DSP - is this correct?
Oddly to me, no matter if CMEM runs or not, output of TOP command remains about the same.
I assume the "temporary filesystems", visible from the output of DF command, occupy RAM space. I would like to know what effects it would have if I unmount these or reduce their size.

CMEMK module:
CMEMK module: built on Mar 24 2011 at 23:44:42
  Reference Linux version 2.6.33
  File /sdk/build/DVSDK_4_02/4_02_00_06/arago-install/arago-tmp/work/da850-omapl
138-evm-none-linux-gnueabi/ti-linuxutils-1_2_26_01_02-r52d/linuxutils_2_26_01_02
/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
allocated heap buffer 0xc5000000 of size 0x2000000
cmemk initialized
DSPLINK Module (1.65.00.02) created on Date: Mar 24 2011 Time: 23:47:38

Memory usage taken from TOP:
Mem: 14444K used, 13520K free, 0K shrd, 2172K buff, 6112K cached

Output from DF:                                                               
Filesystem                     1K-blocks      Used      Available       Use%      Mounted on             
/dev/root                         735252       590524    107380          85%        /                      
tmpfs                                 40               0             40              0%         /mnt/.splash           
none                                1024             28          996              3%         /dev                   
/dev/mmcblk0p2              735252        590524    107380          85%       /media/mmcblk0p2       
/dev/mmcblk0p1               79073         11387      67687           14%       /media/mmcblk0p1       
tmpfs                              16384            28          16356            0%       /var/volatile          
tmpfs                              13980              0          13980            0%       /dev/shm               
tmpfs                              16384              0          16384            0%       /media/ram  

 

2.
Assuming I have 32MB heap buffer for DSP and ARM.

ARM code:
a. char buf[LENGTH];

b. char* buf = (char*) malloc(LENGTH);

c. char* buf = (char*) C6RUN_MEM_malloc(LENGTH);

As I understand it a will allocate memory from the stack, b from the heap, and c from the 32MB CMEM heap. Is that correct?
What if I run these commands in DSP code? Will they all take the requested memory from the CMEM heap?

 

Thanks in advance,

Mathias

  • Mathias Schmitz said:
    I don't think I have understood the memory allocation and usage entirely yet. I'm trying to figure out where I have to allocate RAM space to get what I want.
    As I understand CMEM reserves 32MB for a (dynamic) heap buffer from the OMAP-RAM. This heap can then be used from the ARM and the DSP - is this correct?
    Oddly to me, no matter if CMEM runs or not, output of TOP command remains about the same.
    I assume the "temporary filesystems", visible from the output of DF command, occupy RAM space. I would like to know what effects it would have if I unmount these or reduce their size.

    The way the C6Run framework is setup, part of the CMEM region is essentially a shared heap from which only the ARM can allocate & free, but from which both cores can read and write (the DSP can only get a pointer to a buffer in this region if the ARM passes it to it with a function call).  The size of the shared heap region is configurable during platform selection (see here). The CMEM region of memory is not managed by the Linux kernel and will not appear in any memory listings from Linux.  In fact, the Linux kernel must be specifically told not to use the CMEM region via "mem=" boot arguments. The reason the CMEM size is 32MB is because this covers the actual region the ARM can allocate from, as well as the region where the DSP has its own heap and where the DSP runs code from.  These last points mean it is conceivable that the DSP could return a pointer that it has allocated and the framework could translate it back to a virtual address the ARM could understand (in much the same way that ARM allocated buffers are translated to physical addresses that the DSP can understand).  This feature is not currently implemented, however.

     

    Mathias Schmitz said:

    ARM code:
    a. char buf[LENGTH];

    b. char* buf = (char*) malloc(LENGTH);

    c. char* buf = (char*) C6RUN_MEM_malloc(LENGTH);

    As I understand it a will allocate memory from the stack, b from the heap, and c from the 32MB CMEM heap. Is that correct?
    What if I run these commands in DSP code? Will they all take the requested memory from the CMEM heap?

    a. Will allocate from the ARM stack, not able to passed to the DSP.

    b. Will allocate from the normal Linux heap, not able to be passed to the DSP (unless --C6Run:replace_malloc is used, in which case the standard libc malloc calls all overridden to just map to C6RUN_MEM_malloc)

    c. Will allocate from the shared heap region (which is the first part of the CMEM region), and can be passed to the DSP.

    Running these commands on the DSP are almost the same, except, as I stated before, DSP allocated pointers cannot currently be handed back to the ARM for use.

     

    I hope the above clarified some of what is going on when it comes to memory management.

     

    Regards, Daniel

  • Hi,

    thank you for your reply, really helpful. I had to chew on this a bit. I'll put it in my words to see if I understood correctly.

    There are essentially three memory regions in my view.
    region 1:
    This region the ARM program allocates memory from for its stack and heap. As I understand it, this region is visible from by the TOP command. If that is true I would have about 13MB remaining to run for the ARM process.
    Data is not passable from this region to the DSP.

    region 2:
    This region the DSP uses for its own executable, heap and stack. This region is not managed by the linux kernel and therefore not visible by TOP command. By adjusting the constant DSP_REGION_CODE_SIZE I can change its size.
    Data is not passable from this region to the ARM.

    region 3:
    This region is the shared memory CMEM - also not visible by TOP command. Its size can be altered with DSP_REGION_CMEM_SIZE.
    Data is passable through pointers.


    I checked my top-level makefile:
        DSP_REGION_CMEM_SIZE=0x01000000 \    #16MB
        DSP_REGION_CODE_SIZE=0x01000000 \    #16MB.

    Combined that would make 32MB which is exactly the heap buffer size when I run loadmodules.

    One approach to increase the memory both ARM and DSP can exchange data would be to downsize the DSP_REGION_CODE_SIZE and increase DSP_REGION_CMEM_SIZE.
    Another one I can think of would be to lower the uboot mem variable to let's say 24 MB. Is this possible or is there a some sort of a boundary?


    Regards,
    Mathias

  • Mathias,

    The above looks correct.

    Mathias Schmitz said:
    One approach to increase the memory both ARM and DSP can exchange data would be to downsize the DSP_REGION_CODE_SIZE and increase DSP_REGION_CMEM_SIZE.
    Another one I can think of would be to lower the uboot mem variable to let's say 24 MB. Is this possible or is there a some sort of a boundary?

    Both of these are possibilities.  You must just be careful to manage the Linux mem= boot argument (passed in by u-boot) with the DSP_REGION_BASE_ADDR, DSP_REGION_CMEM_SIZE, and DSP_REGION_CODE_SIZE variables.  You want to make sure things don't overlap and that the total size of memory allocated does not go beyond the physical memory size.

    Regards, Daniel

  • Hi Daniel,

    thanks a lot for your help. Now I feel ready to mess about with this stuff a bit.

     

    Regards,

    Mathias