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.

Can Codec Engine use memory allocated from any Shared Region using SharedRegion_getHeap?

Guru 10685 points
Other Parts Discussed in Thread: SYSBIOS

I need to allocate a big chunk of memory (at least 12MB) to my XDAIS algorithm from the Linux application on my DM8168. At the moment I have something like this in my Linux application:

inBuf = (XDAS_Int8*)Memory_alloc(IFRAMESIZE, &allocParams);

But this only allocates memory out of the small memory area that the cmemk module is told about when I load it. I need to allocate memory from a different segment that has more memory so I thought I'd try to allocate from one of the shared regions.

In this post:

http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/p/224009/789099.aspx

....I'm told about SharedRegion_getHeap and a different form of the Memory_alloc call (maybe only available from the SYSBIOS algorithm???) which has 4 arguments instead of the 2 I've been using above.

If I use SharedRegion_getHeap to allocate memory will this memory be useable by the codec when I pass the address to the algorithm as an argument in my UNIVERSAL_process call? How do I get access to shared memory from Linux?

Sorry if the post is a bit confusing; I'm confused myself about the different forms of Memory_alloc.

Thanks,
Ralph

  • Ralph,

    Could you share some version details ? (Which CE/FC version are you using ?) What is your exact "insmod cmemk" command, and what is the error you see ?

    If memory is being shared between ARM and DSP, it has to be physically contiguous. CMEM is the right way to allocate this memory. As Vimal suggests in the post you link to, you could reduce Linux's memory usage and "insmod" cmem with increased memory.

    Here are some links that may be helpful is figuring out the correct "insmod" command for CMEM.

    http://processors.wiki.ti.com/index.php/Changing_the_DVEVM_memory_map#CMEM:_Contiguous_Memory_Allocator

    http://processors.wiki.ti.com/index.php/Changing_the_DVEVM_memory_map#Sizing_and_partitioning_CMEM_memory

    http://processors.wiki.ti.com/index.php/Codec_Engine_Application_Developers_Guide#What_Happens_to_DSP_Memory_Issues.3F

  • Hi Gunjan,

    I read the links you provided. As I understand it, in my situation CMEM is deprecated as I can use SharedRegion_getHeap instead. On the DM8168 at least, this gives me access to much more memory in the pre-defined memory map, in the form of the so called "Shared Regions".

    Here are my versions, chosen because they were the dependencies listed as supported versions for the latest Codec Engine:

    • bios_6_33_06_50
    • framework_components_3_23_00_13
    • osal_1_23_00_04
    • codec_engine_3_23_00_07
    • linuxutils_3_23_00_01
    • syslink_2_20_00_14

    Here is all of the output (it includes the CMEM command):

    # modprobe syslink
    SysLink version : 2.20.00.14
    SysLink module created on Date:Oct 22 2012 Time:11:01:33
    # insmod /usr/cmemk.ko phys_start=0x96C00000 phys_end=0x98000000 pools=10x104857
    6,10x524288,20x262144 allowOverlap=1
    CMEMK module: built on Oct 26 2012 at 16:03:18
      Reference Linux version 2.6.37
      File /home/ralphc/shark/software/prototypes/dsp_test/cmem/cmemk.c
    cmemk initialized
    # /usr/testpatternapp.xv5T
    Start SysLink
    [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=0x4005a000] 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=0x4005a000] 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.

    Also, here is the core of the code that I am using:

    SysLink_setup();

    /* init Codec Engine */
    CERuntime_init();

    /* Enable all trace for xdc.runtime.Main */
    Diags_setMask("xdc.runtime.Main+EX1234567");

    Log_print0(Diags_USER2, "main> dsp_test.application.testpatternapp");

    /*
     * Create the Engine with a remote Server and add register the
     * appropriate stub functions.
     *
     * Note, this can also be done in a config script.
     */
    retVal = Engine_addStubFxns("UNIVERSAL_STUBS",
                                         (IALG_Fxns*)&UNIVERSAL_STUBS);
    if(retVal != Engine_EOK)
    {
        printf("App-> ERROR: Runtime Engine_addStubFxns() failed (0x%x)\n",
                 retVal);
        goto end;
    }

    if((multiProcId = getMultiProcId(procId)) == NULL)
    {
        printf("main-> ERROR: Invalid processor name: %s\n", procId);
        goto end;
    }

    sprintf(defaultEngineName, "remote_copy_%s", procId);

    /* Add an engine for each slave processor */
    Engine_initDesc(&engDesc);
    engDesc.name = "remote_copy_dsp";
    engDesc.memMap = mapFileName;
    engDesc.remoteName = "servercom.xe674";    // <name given in genserver>.xe674

    retVal = Engine_add(&engDesc);
    if(retVal != Engine_EOK)
    {
        printf("main-> ERROR: Runtime Engine_add() failed (0x%x)\n", retVal);
        goto end;
    }

    /* create the input file if it doesn't already exist */
    createInFileIfMissing(inFile);

    Log_print3(Diags_USER1, "[+1] App-> Application started."
                  "engineName %s input-file %s output-file %s.",
                  (IArg)engineName, (IArg)inFile, (IArg)outFile);

    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);
        }
    }

    Thanks for your help.
    Ralph


  • From your output, it seems like SysLink_Setup call if failing. In fact, per the code, SysLink_Setup should be getting called during CERuntime_init (via Processor_init). So I am not sure why you attempting to call it before ?

    Also you can run this app with "CE_DEBUG=3" to see some trace output.

  • Ralph, 

    Spoke to my team here. The issue seems to be that you are trying to access the SharedRegion heap handle before the DSP gets loaded. You might want to "getHeap" and then "alloc" after DSP is loaded, i.e, after a successful Engine_open() call.

    Can you give that a try ?

    Thanks,

    Gunjan.

  • Hi Gunjan,

    I'm pleased to say that your suggestion worked. I had to make the getHeap call after Engine_open.I can now getHeap for region 0 and 1, but unfortunately I can't get anything from region 2 which is where I want to get memory from as it's my largest region.

    Is it worth me posting my config.bld for my application? Here it is (I am expecting the shared regions named DDR3_SRX in this to be used by the getheap call - is this assumption correct?):

    var Build = xdc.useModule('xdc.bld.BuildEnvironment');

    var TI816X_DSP_ExtMemMap = {
                DDR3_HOST: {
                    comment: "DDR3 Memory reserved for use by the A8",
                    name: "DDR3_HOST",
                    base: 0x80000000,
                    len:  0x16C00000
                },
                DDR3_DSP: {
                    comment: "DDR3 Memory reserved for use by the C674",
                    name: "DDR3_DSP",
                    base: 0x99500000,
                    len:  0x00C00000
                },
                DDRALGHEAP: {
                    comment: "DDR3 Memory reserved for use by algorithms on the C674",
                    name: "DDRALGHEAP",
                    base: 0x98000000,
                    len:  0x01400000
                },
                    DDR3_SR2: {
                    comment: "DDR3 Memory reserved for use by SharedRegion 2",
                    name: "DDR3_SR2",
                    base: 0xB3D00000,
                    len:  0x0BC00000
                },
                DDR3_SR1: {
                    comment: "DDR3 Memory reserved for use by SharedRegion 1",
                    name: "DDR3_SR1",
                    base: 0x9A100000,
                    len:  0x00100000
                },
                DDR3_SR0: {
                    comment: "DDR3 Memory reserved for use by SharedRegion 0",
                    name: "DDR3_SR0",
                    base: 0x9F700000,
                    len:  0x00200000
                },
    };

    /* platform instances used by this package */
    Build.platformTable["ti.platforms.evmTI816X:DSP"] = {
        externalMemoryMap: [
        [ "DDR3_DSP",   TI816X_DSP_ExtMemMap.DDR3_DSP ],
        [ "DDRALGHEAP", TI816X_DSP_ExtMemMap.DDRALGHEAP ],
        [ "DDR3_SR2",   TI816X_DSP_ExtMemMap.DDR3_SR2 ],
        [ "DDR3_SR1",   TI816X_DSP_ExtMemMap.DDR3_SR1 ],
        [ "DDR3_SR0",   TI816X_DSP_ExtMemMap.DDR3_SR0 ]
        ],
        codeMemory: "DDR3_DSP",
        dataMemory: "DDR3_DSP",
        stackMemory: "DDR3_DSP"
    };

    Thanks,


    Ralph

  • Looking in my codec server, I noticed this in the server.cfg:

    /*
     *  Configure CE's OSAL.  This codec server only builds for the BIOS-side of
     *  a heterogeneous system, so use the "DSPLINK_BIOS" configuration.
     */
    var osalGlobal = xdc.useModule('ti.sdo.ce.osal.Global');
    osalGlobal.runtimeEnv = osalGlobal.DSPLINK_BIOS;


    /* IPC-related config */
    xdc.useModule('ti.sdo.ce.ipc.dsplink.dsp.Settings');
    var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
    var settings = xdc.useModule('ti.sdo.ipc.family.Settings');
    var procNames = settings.getDeviceProcNames();

    MultiProc.setConfig("DSP", procNames);

    var SharedRegion_map = {};
    SharedRegion_map["SysLink: HOST<--->DSP"] = 0;
    SharedRegion_map["Ipc"] = 1;
    var SharedRegion  = xdc.useModule('ti.sdo.ipc.SharedRegion');
    var syslinkSharedMem = Program.cpu.memoryMap["DDR3_SR0"];
    var ipcSharedMem = Program.cpu.memoryMap["DDR3_SR1"];
    var entry = new SharedRegion.Entry();

    entry.base = syslinkSharedMem.base;
    entry.len = syslinkSharedMem.len;
    entry.ownerProcId = MultiProc.getIdMeta("HOST");
    entry.isValid = true;
    entry.name = "SYSLINK";

    SharedRegion.setEntryMeta(
        SharedRegion_map["SysLink: HOST<--->DSP"],  /* index */
        entry
    );

    var entry2 = new SharedRegion.Entry();

    entry2.base = ipcSharedMem.base;
    entry2.len = ipcSharedMem.len;
    entry2.ownerProcId = MultiProc.getIdMeta("HOST");
    entry2.isValid = true;
    entry2.createHeap = true;
    entry2.cacheEnable = true;
    entry2.name = "SR1";

    SharedRegion.setEntryMeta(
        SharedRegion_map["Ipc"],  /* index */
        entry2
    );

    i.e. no setup for SharedRegion2, probably because I only just added it to the config.bld.

    How do I make the codec server on the DSP "see" this memory?

    Thanks,

    Ralph

  • YES!!! It works!!! Down with CMEM!

    I updated the server memory map and it runs fine. Another question entirely whether it will play nicely with OpenMAX applications of course but that's for another day. (I assume it will as if the memory maps are the same and OpenMAX is using Syslink to allocate memory, everything should cooperate).

    Just before I close the thread, is there any way I can get the physical address where Memory_alloc is allocating memory?

    Gunjan, you've helped me fix a problem that I had in a recent previous thread thought couldn't be resolved. Thank you.

    Ralph

  • Good to know you are able to proceed. Credit to Janet from my team (who has also answered some other related posts).

    As far as obtaining physical address, may be look into this API, it seems to do what you need:-

    Int ProcMgr_translateAddr ( ProcMgr_Handle
    handle,
    Ptr *
    dstAddr,
    ProcMgr_AddrType
    dstAddrType,
    Ptr
    srcAddr,
    ProcMgr_AddrType
    srcAddrType
    )
    Translate between two types of address spaces.
    Remarks:
    This function translates addresses between two types of address spaces. The destination and source address types are indicated through parameters specified in this function.
    Parameters:
    [in] handle Handle to the ProcMgr object
    [out] dstAddr Return parameter: Pointer to receive the translated address.
    [in] dstAddrType Destination address type requested
    [in] srcAddr Source address in the source address space
    [in] srcAddrType Source address type
    Return values:
    ProcMgr_S_SUCCESS Operation successful
    ProcMgr_E_INVALIDARG Invalid parameter specified
    ProcMgr_E_INVALIDSTATE Module was not initialized
    ProcMgr_E_HANDLE Invalid NULL handle specified
    ProcMgr_E_TRANSLATE Failed to translate address.
    ProcMgr_E_OSFAILURE Failed in an OS-specific call

  • Thanks for that. By the way, am I right in assuming that Memory_alloc will return contiguous memory? I can't tell from the documentation (http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/syslink/latest/docs/html/_memory_8h.html#ac65884b6624cdb8bb6274ce4ce1f439c)

  • Makes sense that it would be contiguous.

  • Okay thanks, I was just thinking that if it were called from Linux it might not be.