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.

HeapBufMP_open failed in MessageQ example

Other Parts Discussed in Thread: SYSBIOS

Hi,

Platform:EVM6472
XDCtools version: 3.20.04.68
IPC: 1.21.02.23
BIOS: 6.30.03.46
XDAIS: 6.25.01.08
CCS Version: 4.2.0.10018

Based on the MessageQ example(C:\Program Files\Texas Instruments\ipc_1_21_02_23\packages\ti\sdo\ipc\examples\multicore\c6472), I create a large  heap(size = 0x8000000) because I want to allocate a large buffer buf(1024*1024) using Memory_alloc in core0 in the future. Now I just modified .cfg file as follows.

    /* Create a Heap. */
   var heapMemParams = new HeapMem.Params();
   heapMemParams.size = 0x8000000;
   heapMemParams.sectionName = "systemHeapMaster";
   Program.global.heap0 = HeapMem.create(heapMemParams);
   Memory.defaultHeapInstance = Program.global.heap0;

   Program.heap = 0x1000;
   Memory.defaultHeapSize = 0x8000000;
   Program.sectMap["sysmemHeapMaster"]  = "DDR2";

   /* Shared Memory base address and length */
   var SHAREDMEM           = 0x200000;
   var SHAREDMEMSIZE       = 0xC0000;
   var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
  SharedRegion.setEntryMeta(0,
      { base: SHAREDMEM,
        len:  SHAREDMEMSIZE,
        ownerProcId: 0,
        isValid: true,
        cacheLineSize: 64, /* SL2 memory has a cache line size of 64 */
        name: "SL2_RAM",
    });

But six cores can't send and receive messages. I add System_printf sentence after HeapBufMP_open and find the problem.

 do {
        status = HeapBufMP_open(HEAP_NAME, &heapHandle);
        System_printf("status=%d\n",status);
    } while (status < 0);

Core1,core4 and core5  get status = 0. But core2 and core3 loops at HeapBufMP_open function and print nothing.

The heap I created just  reflect buf created through Memory_alloc. Why doesn't HeapBufMP_open work? Who can tell me the reason? 

  • Hi Mary,

    This could be a problem due to the issue Judah pointed out in your other forum post.  Please try fixing that and see if this is still an issue.

    Regards,

    Shreyas

  • Hi Shreya,

     I just create a heap to modify .cfg file and don't add Memory_alloc to message_single.c . I don't know why some cores can get the right value status=0 but others can't get value of status at HeapBufMP_open . 

    Core1-core5 can get status=0 and transfer the message when I point sysmemHeapMaster  to LL2RAM. So I want to know whether the default heap can be allocated at DDR2  in MessageQ .   

      var heapMemParams = new HeapMem.Params();
       heapMemParams.size = 0x8000;
       heapMemParams.sectionName = "systemHeapMaster";
       Program.global.heap0 = HeapMem.create(heapMemParams);
       Memory.defaultHeapInstance = Program.global.heap0;

       Program.heap = 0x1000;
       Memory.defaultHeapSize = 0x8000;
       Program.sectMap["sysmemHeapMaster"]  = "LL2RAM";

    But the heap is too small for buf[1024*1024]. How to create a heap or congfigure .cfg file for Memory_alloc and MessageQ ? 

     Attach my application here. Please give some suggestions.

         7534.MessageQ.rar

    Thanks!

          

  • Hi Mary,

    The default heap must be local to each core.  Since you are placing the default heap in the same address in DDR across all the cores, this will be a problem since each core will overwrite each other's data that has been allocated for local use. A straightforward way to fix your application is as follows:

    1) Do not set Memory.defaultHeapInstance to a heap that is placed in shared memory.  Create a separate heap in shared memory that is used with MessageQ (see step 2). Remove the following lines (in RED):

      var heapMemParams = new HeapMem.Params();
       heapMemParams.size = 0x8000;
       heapMemParams.sectionName = "systemHeapMaster";
       Program.global.heap0 = HeapMem.create(heapMemParams);
       Memory.defaultHeapInstance = Program.global.heap0;

       Program.heap = 0x1000;
       Memory.defaultHeapSize = 0x8000;
       Program.sectMap["sysmemHeapMaster"]  = "LL2RAM";

    2) Create a SharedRegion '1' that is placed in DDR.  On C6472, SR #0 must reside in SL2RAM, so you can't simply relocate this heap to DDR. The following code can achieve this:

    SharedRegion.setEntryMeta(1,
        { base: DDRBASEADDR,  //need to define this somewhere
          len:  DDRLENGTH,   //need to define this somewhere
          ownerProcId: 0,
          isValid: true,
          name: "DDR_RAM",
        });

    3) When you create another shared region, IPC internally creates a HeapMemMP instance to manage the memory assigned to it (i.e. in step 2).  At run-time, you can retrieve a handle to this heap by calling SharedRegion_getHeap(1) where '1' is the correspodning shared region id.

    4) You can use this heap as you see fit--you may register it with MessageQ using MessageQ_registerHeap or you may directly allocate memory from it using Memory_alloc.

    Regards,

    Shreyas

  • Hi Shreya,

    Thanks for your good idea. I modified my .cfg file as you suggested and the application runs well. I want to add NDK code in helloworld example to the program , so I add emacComm section and Global module. Then I point section .text to DDR2. The program runs well too. This is the configuration.                                                    

    Program.heap = 0x9000;
    Memory.defaultHeapSize = 0x9000; 

    Program.sectMap["emacComm"] = "DDR2";
    Program.sectMap[".text"] = "DDR2";

    /* Shared Memory base address and length */
    var SHAREDMEM           = 0x200000;
    var SHAREDMEMSIZE       = 0xC0000;
    var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
    SharedRegion.setEntryMeta(0,
        { base: SHAREDMEM,
          len:  SHAREDMEMSIZE,
          ownerProcId: 0,
          isValid: true,
          cacheLineSize: 64, /* SL2 memory has a cache line size of 64 */
          name: "SL2_RAM",
        });
     
    /* DDR Shared Memory base address and length */
    var DDRBASEADDR          = 0xe0000000;
    var DDRLENGTH       = 0x8000000;
    SharedRegion.setEntryMeta(1,
    { base: DDRBASEADDR, 
      len:  DDRLENGTH,  
          ownerProcId: 0,
          isValid: true,
          name: "DDR_RAM",
        });

    And I define localQueueName and nextQueueName as the local variables from global varibles.

    Void tsk0_func(UArg arg0, UArg arg1)
    {
        Char localQueueName[6];
        Char nextQueueName[6];
    }
    Void tsk1_func(UArg arg0, UArg arg1)
    {
        Char localQueueName[6];
        Char nextQueueName[6];
    }        

     Because there will be more global variables in the future program, so I must point section .far to DDR2,too. Add the following line.

       Program.sectMap[".far"] = "DDR2";

    Rebuild the program and run .out file on six cores,it abort at core0 and displays the following line.

    To see more exception detail, use ROV or set 'ti.sysbios.family.c64p.Exception.enablePrint = true;'
    Exception abort!     

                       

    I don’t know what is wrong with it from ROV window.I know that section .far stores the global variable and static variables from TMS320C6000 Compiler Document. But I have defined localQueueName and nextQueueName as the local variables.
    Does .far reflect MessageQ? Attach my program here.2806.MessageQ_heap.zip

    Thanks!
                  

  • Hi Mary,

    I don't think it's OK to insert the following line into your .cfg file without a good amount of additional work:

        Program.sectMap[".far"] = "DDR2";

    Not only will this relocate your own variables to DDR2, but this will also relocate XDC/BIOS/IPC *local* state there as well.  As a consequence, multiple cores may use the same memory that should be private to each individual core (similar to the problem I discussed earlier).   I think the best way of placing your variables in DDR2 is to create a new linker section that is placed in DDR2 and then placing your global variables in that linker section.

    So in your .cfg file, you could create a new linker section as follows:

               Program.sectMap["my_section"] = new Program.SectionSpec();
               Program.sectMap["my_section"].loadSegment = "DDR2";

    And in your C file, you can place your global variables in this section as follows:

        #pragma DATA_SECTION(my_variable, "my_section");

    Regards,

    Shreyas

  • Hi Shreyas,

    As you said, it's not a good idea to insert the line.

             Program.sectMap[".far"] = "DDR2";

    I added this line because when I add the ndk code from helloworld it tell me .far out of memory.  Then I find  the size of  .far:NDK_PACKETMEM is large. So  I delete the last line and just add the line.

          Program.sectMap[".far:NDK_PACKETMEM"] = {loadSegment: "DDR2", loadAlign: 128};

    Then the progamm works well and MessageQ can send and receive messages among six cores.

    Thanks ! I'll take your idea in the future.