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.

Using Memory_alloc() to allocate large amounts of memory in Shared Regions and making this work with OpenMAX

Guru 10685 points
Other Parts Discussed in Thread: SYSBIOS

I am using the memory copy algorithm from Codec Engine's GenAlg wizard as the basis for my own graphical effects algorithm to run on the DSP side of the DM8168. My first hurdle is to allocate (from the ARM application) input and output buffers each of size 1920x1080x3= ~6MB to act as framebuffers.

Unfortunately in the default memory map for the DM8168 only 20MB is allocated to CMEM, and hence after loading my cmemk module and then running my application, it fails at the call to "Memory_alloc".

When loading my cmemk module, I could tell it to allocate memory from one of the Shared Memory regions (as reserved for OpenMAX applications as I understand it) but then how would I tell my OpenMAX encoding application (that runs in parallel with my DSP application) about this used memory so that OpenMAX didn't use the memory allocated by Codec Engine?

Thanks,
Ralph

P.S.

I know some people are using the VLPB OpenMAX component to manage DSP processing (and thus it doesn't need to manage memory use on the DSP for Codec Engine as Codec Engine isn't in use) but this doesn't seem to be too well supported at the moment so I'm avoiding it.

  • Is it mandatory to use cmem for your DSP algorithm. Your ARM application could directly allocate buffers from shared region.

    To allocate buffers use:

    IHeap_Handle srHeap = SharedRegion_getHeap(SrIndex);

    Memory_alloc(srHeap, size,..);

    Refer <ipc_package>/ti/ipc/SharedRegion.h for detailed API documentation.

  • Hi Badri,

    Sorry for asking but was your first sentence a question or were you stating a fact?

    The SharedRegion_getHeap looks like the business. Will this - when coupled with Memory_alloc - ensure that any running OpenMAX applications will not use the memory allocated to the DSP-Codec Engine application? (I'll be using SharedRegion_getHeap + Memory_alloc in the Codec Engine application).

    Many thanks,

    Ralph

  • First sentence was a question.If you are going to use CE framework there may be restrictions that force you to use memory from cmem.I dont think this is the case but I am not sure about this. Pls get it confirmed in the codec engine forum.

    Regarding "Will this - when coupled with Memory_alloc - ensure that any running OpenMAX applications will not use the memory allocated to the DSP-Codec Engine application? (I'll be using SharedRegion_getHeap + Memory_alloc in the Codec Engine application)."

    -- The memory is allocated from a shared memory heap and any memory allocated to DSP application will not be available to openMax.

    Regards

    Badri

  • :-) In that case, the answer is no, it is not mandatory for us to use CMEM but of course as the memory allocated will be used by Codec Engine perhaps it is mandatory.... I know that there is some connection between Codec Engine and CMEM, I'm just not sure myself either how this works.

    Badri Narayanan said:
    -- The memory is allocated from a shared memory heap and any memory allocated to DSP application will not be available to openMax.

    That's great to know. I'll stick a post on the Multimedia Software Codecs forum and see what happens.

    Ralph

  • One more question:

    the Memory_alloc() function you referred to is a SYSBIOS only function is it not? How do I call this function from my Linux application?

    Thanks,
    Ralph

  • Ralph,

    Memory_alloc can be used in Linux as well. It is taken care by OSAL. BTW, allocation of buffers in Linux, is given in decode_mosaic example, which I have referred you earlier as well. If you need more space in CMEM, you can reduce Linux memory and use it in CMEM.

    Regards

    Vimal

  • Hi Vimal,

    Thanks for the reply. How do I get Memory_alloc (in OSAL as used by Linux) to allocate memory from somewhere other than the CMEM module pools?

    1) The Memory_AllocParams struct that is passed to Memory_alloc contains a "seg" field - the documentation says that this is the "Segment for allocation" but what does that mean exactly? Does this indicate which number shared region to allocate from?

    The other interesting parameter passed in the struct is an enum with these fields:

    Memory_MALLOC     
    malloc()-based allocation

    Memory_SEG
    DSP/BIOS segment-based allocation

    Memory_CONTIGPOOL     
    Contiguous, pool-based allocation

    Memory_CONTIGHEAP     
    Contiguous, heap-based allocation

    2) Which one do I want to allocate from shared memory? Presumably it must be contiguous for codec engine and as it's from the heap, I am guessing I should go for Memory_CONTIGHEAP but I'm not certain.

    3) I've had a look in the decode_mosaic demo and seen how the Memory_alloc call is made, but I suppose I'm asking, why are there 2 different Memory_alloc functions?

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/syslink/latest/docs/html/_memory_8h.html#ac65884b6624cdb8bb6274ce4ce1f439c

    and

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/ce/latest_2_x/docs/html/group__ti__sdo__ce__osal___memory.html#gad526de48c332226c46d312a512566a09

    Thanks,

    Ralph

  • Update:

    I've tried this in my Linux application:

    for(regionId=0; regionId<3; regionId++)
        {
            allocParams.type = Memory_CONTIGHEAP;
            allocParams.flags = Memory_NONCACHED;
            allocParams.align = BUFALIGN;
            allocParams.seg = regionId;
        
            inBuf = (XDAS_Int8*)Memory_alloc(IFRAMESIZE, &allocParams);
            pointy = Memory_getBufferPhysicalAddress(inBuf, IFRAMESIZE, &isContiguous);
            if(!pointy)
            {
                printf("Couldn't get buffer physical address.\n");
            }
            else
            {
                printf("Allocated input buffer memory at physical address %p, %scontiguous.\n", pointy, isContiguous ? "" : "non-");
            }
        }

    and I just get a load of "CMEMK Error: ioctl: no heap available in block 0" messages. :-(

    Ralph

  • I'm trying something else now. I've managed to include the Syslink version of Memory_alloc rather than the Codec Engine version (God knows why they have the same name.....).

    Unfortunately, unlike the decode_mosaicdisplay demo it just won't allocate memory for me. Here's the code:

    for(regionId=0; regionId<3; regionId++)
        {
            heap = (IHeap_Handle)SharedRegion_getHeap(regionId);  // get the heap
            if(!heap)
            {
                printf("Couldn't get heap handle for region %d.\n", regionId);
            }
            else
            {
                pointy = Memory_alloc(heap, IFRAMESIZE, 128, NULL);
                if(!pointy)
                {
                    printf("Buffer allocation failed.\n");
                    return 0;
                }
                
                printf("Allocated input buffer memory at address %p.\n", pointy);
            }
        }

    And here's the error message when I run the code:

    # /usr/testpatternapp.xv5T
    [t=0x00000000] [Assertion at Line no: 467 in /home/ralphc/shark/software/bsp/core/build/syslink-2_20_00_14/packages/ti/syslink/utils/hlos/knl/Linux/../../../../../../ti/syslink/ipc/hlos/knl/Linux/SharedRegionDrv.c: (heapHandle != NULL) : failed
    tid=0x400d1000] xdc.runtime.MainAssertion at Line no: 467 in /home/ralphc/shark/software/bsp/core/build/syslink-2_20_00_14/packages/ti/syslink/utils/hlos/knl/Linux/../../../../../../ti/syslink/ipc/hlos/knl/Linux/SharedRegionDrv.c: (heapHandle != NULL) : failed
    : main> dsp_test.application.tesAssertion at Line no: 467 in /home/ralphc/shark/software/bsp/core/build/syslink-2_20_00_14/packages/ti/syslink/utils/hlos/knl/Linux/../../../../../../ti/syslink/ipc/hlos/knl/Linux/SharedRegionDrv.c: (heapHandle != NULL) : failed
    tpatternapp
    Input file './in.dat' not found, generating one.
    [t=0x000003d1] [tid=0x400d1000] xdc.runtime.Main: [+1] App-> Application started.engineName remote_copy_dsp input-file ./in.dat output-file ./out.dat.
    Assertion at Line no: 1349 in /db/atree/library/trees/sl/sl-d14/src/packages/ti/syslink/product/export/syslink_2_20_00_14/packages/ti/syslink/../../ti/syslink/ipc/hlos/usr/HeapMemMP.c: (hpHandle != NULL) : failed
    Couldn't get heap handle for region 0.
    Assertion at Line no: 1349 in /db/atree/library/trees/sl/sl-d14/src/packages/ti/syslink/product/export/syslink_2_20_00_14/packages/ti/syslink/../../ti/syslink/ipc/hlos/usr/HeapMemMP.c: (hpHandle != NULL) : failed
    Couldn't get heap handle for region 1.
    Assertion at Line no: 1349 in /db/atree/library/trees/sl/sl-d14/src/packages/ti/syslink/product/export/syslink_2_20_00_14/packages/ti/syslink/../../ti/syslink/ipc/hlos/usr/HeapMemMP.c: (hpHandle != NULL) : failed
    Couldn't get heap handle for region 2.

    Any ideas how to persuade the SharedRegion_getHeap function to work?

    Thanks,
    Ralph

  • Some things I can think of:

    1. Dont have for loop. You should pass a single shared region id and alloc from it.If it done for debug purpose ignore this comment.

    2. Shared regions are setup after firmware is loaded and Syslink_setup is invoked by the application. Pls check if this is the case in your case.You can refer decode_mosaicdisplay to check the initial setup done before Memory_alloc from shared region is done.

    3. If you are able to get heap handle for Sr0 and Sr1 but not Sr2 it may be because SharedRegion2 is not enabled on A8.Pls check if SharedRegion_getHeap fails only for a particular SrId.

  • Hi,

    You should call OMX_Init() or SysLink_setup() function prior to use Memory_alloc().

    Please see detailed explanation with different scenarios here:

    http://e2e.ti.com/support/embedded/linux/f/354/t/202453.aspx

    Regards,

    Krunal

  • 1) Yes it's just for debug to check that the framework is seeing my shared regions in the right place in the memory map.

    2) I wasn't calling SysLink_setup so thanks for that. I was calling CERuntime_init which might already call that function but from a quick check of the function definition it doesn't seem to be. However, now that I've put SysLink_setup in there, it doesn't change anything at all in the printed output from the app. :-/

    3) I don't get any heap handles at all for SR0, SR1 or SR2.

    I note that the decode_mosaicdisplay program calls OMX_Init() before doing anything. I had a look in OMX_Init() and saw that the only non-OMX function call was to SysLink_setup.

    Is there anything else I can do to debug this?

    Thanks,

    Ralph

  • Krunal, thanks for your reply. I had a read of the thread (I think I read it when it was being written too) and see that your problem appeared to give a different error message to mine, which was solved by inserting the missing SysLink_setup() function call.

    As I say, I've tried that but not had any luck.

    The only thing I've done differently is not call OMX_Init but I really don't want to do that yet as it's meant to be staying a Codec Engine application!

    Thanks,
    Ralph

    Update:

    I tried running OMX_Init in a different application before running my codec engine application but _still_ no luck.

  • Ralph,

    OMX_init does set_entry for shared regions. ( in EZSDK 5.05, firmware loader also creates shared regions ( except 'SR0' , which would get created while loading M3 firmware). So if application does not recognize shared region, it can not be used. It would be required in DSP as well.

    Also if you use SR with CE, address translation would be required on DSP/A8 for buffer communication. I am not sure if CE supports that.

    Regards

    Vimal

  • Hi Vimal,

    It's good to know how to do this but... I can see that CE was not designed for this use case and you're just meant to stick with CMEM so this is what I'll do.By the way, I found the bit of code with the SharedRegion_setEntry in.

    I'll investigate VLPB/OMX briefly and then make a decision on how I want to do things.

    Thanks for all the replies.

    Ralph