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.

Failure when using both GateMP and Intc

Other Parts Discussed in Thread: SYSBIOS

I am developing code for C6678 involving multicore communications/synchronization. Now I encoutered a problem, i.e., using GateMP will fail if Intc is intialized. The tool chain I am using is listed below:

MCSDK: 2.0.1.12

C6678 PDK: 1.0.0.12

IPC: 1.23.0.26

Sys/BIOS: 6.32.01.38

XDC: 3.22.01.21

TI Compiler: 7.3.0

CCS: 5.0.3.00028

The two files at the end of this posting should reproduce the problem. The problem is that calling  CSL_intcInit before calling GateMP_open() by cores 1 to 7 will cause failure in finding the named GateMP created by core 0. If I comment out the line calling  InitIntc() in tsk0_func, calling GateMP_open(0 will succeed after a few loop iterations. Another (related) problem is if I do Intc initialzation after all cores have the GateMP opened, then using the GateMP will causes an assertion failure for cores 1 to 7 with the error message:

ti.sdo.ipc.GateMP: line 208: assertion failure: A_nullArgument: Required argument is null

I would be very grateful for reasons of and solutions to the problem.

Dongning

 

--------------------------------- main.cpp -------------------------------

 

#include <xdc/std.h>
#include <string.h>

#include <xdc/runtime/System.h>

#include <ti/ipc/Ipc.h>
#include <ti/ipc/MultiProc.h>

#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>

#include <xdc/cfg/global.h>

#include <ti/ipc/GateMP.h>
#include <ti/csl/src/intc/csl_intc.h>

static Char gateMpName[] = "myGateMpName";
static int regionId = 0;
CSL_IntcContext   intcContext;

enum{
  NUM_INTCS = 2, // Only INTC0 and INTC1 can generate interrupt to core
  NUM_HANDLERS = 10
};

CSL_IntcEventHandlerRecord  EventHandler[NUM_HANDLERS];

void InitIntc(Int32 intcNum)
{
  if(intcNum < 0 || intcNum >= NUM_INTCS)
  {
    System_printf("There are only 4 INTCs!");
    return;
  }

  intcContext.eventhandlerRecord = EventHandler;
  intcContext.numEvtEntries      = NUM_HANDLERS;
  if (CSL_intcInit(&intcContext) != CSL_SOK)
  {
    System_printf("Error: GEM-INTC initialization failed\n");
    return;
  }   

}

extern "C" Void tsk0_func(UArg arg0, UArg arg1)
{
  int coreId = MultiProc_self();
  System_printf("tsk0_func%d\n", coreId);

  InitIntc(coreId >> 2);

  Int              status;
  GateMP_Handle m_handle = NULL;

  if (MultiProc_self() == 0) {

    GateMP_Params params;
    GateMP_Params_init(&params);
    params.localProtect = GateMP_LocalProtect_THREAD;
    params.remoteProtect = GateMP_RemoteProtect_SYSTEM;
    params.name = gateMpName;
    params.regionId = regionId;
    m_handle = GateMP_create(&params);

    System_printf("GateMP_create(%08x)\n", m_handle);

  }
  else {

    do {
      status = GateMP_open(gateMpName, &m_handle);
      if (status < 0) {
        Task_sleep(1);
      }
    } while (status < 0);

    System_printf("GateMP_open(%08x)\n", m_handle);

  }

  System_printf("The test is complete\n");
}

Int main(Int argc, Char* argv[])
{
  Int status = Ipc_start();
  if (status < 0) {
    System_abort("Ipc_start failed\n");
  }

  BIOS_start();

  return (0);
}


------------------------ cfg file ----------------------------------

switch (Program.platformName) {
    case "ti.sdo.ipc.examples.platforms.evm6670.core0":
        var nameList = ["CORE0", "CORE1", "CORE2", "CORE3"];
        break;
    case "ti.sdo.ipc.examples.platforms.evm6678.core0":
        var nameList = ["CORE0", "CORE1", "CORE2", "CORE3",
                        "CORE4", "CORE5", "CORE6", "CORE7"];
        break;
    case "ti.platforms.evm6678":
        var nameList = ["CORE0", "CORE1", "CORE2", "CORE3",
                        "CORE4", "CORE5", "CORE6", "CORE7"];
        break;
    default:
        throw("Platform " + Program.platformName + " not supported by this example");
        break;
}

var Timestamp = xdc.useModule('xdc.runtime.Timestamp');
var GateMP = xdc.useModule('ti.sdo.ipc.GateMP');
var Settings = xdc.useModule('ti.csl.Settings');
Settings.useCSLIntcLib = true;

var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
MultiProc.setConfig(null, nameList);
                          
/*
 *  The SysStd System provider is a good one to use for debugging
 *  but does not have the best performance. Use xdc.runtime.SysMin
 *  for better performance.
 */
var System   = xdc.useModule('xdc.runtime.System');
var SysStd   = xdc.useModule('xdc.runtime.SysStd');
System.SupportProxy = SysStd;

var Ipc         = xdc.useModule('ti.sdo.ipc.Ipc');
var MultiProc   = xdc.useModule('ti.sdo.utils.MultiProc');

/* BIOS/XDC modules */
var BIOS        = xdc.useModule('ti.sysbios.BIOS');
BIOS.heapSize   = 0x8000;
var Task        = xdc.useModule('ti.sysbios.knl.Task');

var tsk0 = Task.create('&tsk0_func');
tsk0.instance.name = "tsk0";

/* Synchronize all processors (this will be done in Ipc_start) */
Ipc.procSync = Ipc.ProcSync_ALL;

/* Shared Memory base address and length */
var SHAREDMEM           = 0x0C000000;
var SHAREDMEMSIZE       = 0x00200000;

/*
 *  Need to define the shared region. The IPC modules use this
 *  to make portable pointers. All processors need to add this
 *  call with their base address of the shared memory region.
 *  If the processor cannot access the memory, do not add it.
 */
var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
SharedRegion.setEntryMeta(0,
    { base: SHAREDMEM,
      len:  SHAREDMEMSIZE,
      ownerProcId: 0,
      isValid: true,
      name: "DDR2 RAM",
    });
/*
 *  @(#) ti.sdo.ipc.examples.multicore.evm667x; 1, 0, 0, 0,86; 6-18-2011 17:34:50; /db/vtree/library/trees/ipc/ipc.git/src/ ipc-g26
 */

 

  • The GateMP error corresponds exactly to that whatever the code you were using made the call GateMP_enter(NULL), whatever the input variable was, the value was NULL.

     

    According to the CSL documentation (pdk_6678/packages/ti/csl/docs/doxygen/html/index.html):

     

    NOTE: The CSL 3.0 INTC module is delivered as a separate library from the remaining CSL modules. When using an embedded operating system that contains interrupt controller/dispatcher support, do not link in the INTC library. For interrupt controller support, DSP/BIOS users should use the HWI (Hardware Interrupt) and ECM (Event Combiner Manager) modules supported under DSP/BIOS v5.21 or later.

     

    Hwi's are described in detail in the SYS/BIOS User Guide (bios_xx_xx_xx/docs/User_Guide.pdf). I've found them very easy to use (but there are many things you must not do while executing a Hwi, such as calling System_printf while using SysStd instead of SysMin)

  • The CSL part of the PDK comes with a sample cpintc. Using this sample, I have succeeded in handling interrupt when EDMA is completed. For this what I use is CSL by setting the following in cfg file.

    var cslSettings = xdc.useModule ('ti.csl.Settings');
     
    cslSettings.useCSLIntcLib = true;


    I will try to use ti.sysbios.hal instead to see if this module resolves the problem.

    Thank you for your help.

    Dongning

     

  • Instead of using "ti.sysbios.hal.Hwi", I used "ti.sysbios.family.c66.tci66xx.CpIntc" to handle Edma transfer completion. The latter is similar to Intc in CSL. However, I could not have my plugin gets called. I find that the module of "ti.sysbios.family.c66.tci66xx.CpIntc" seems to module C6670 instead of C6678 even if my project's platform is configured as "ti.platform.evm6678". I find this by the following code:

      if(0 == coreId)
      {
        for(int i = 0; i < 17; ++i)
        {
          Int eventId = CpIntc_getEventId(i);
          printf("hostInt(%d), eventId(%d), coreId(%d)\n", i, eventId, coreId);
        }
      }

    This code generates the following:

    [C66xx_0] hostInt(0), eventId(56), coreId(0)
    [C66xx_0] hostInt(1), eventId(57), coreId(0)
    [C66xx_0] hostInt(2), eventId(58), coreId(0)
    [C66xx_0] hostInt(3), eventId(59), coreId(0)
    [C66xx_0] hostInt(4), eventId(60), coreId(0)
    [C66xx_0] hostInt(5), eventId(61), coreId(0)
    [C66xx_0] hostInt(6), eventId(62), coreId(0)
    [C66xx_0] hostInt(7), eventId(63), coreId(0)
    [C66xx_0] hostInt(8), eventId(74), coreId(0)
    [C66xx_0] hostInt(9), eventId(75), coreId(0)
    [C66xx_0] hostInt(10), eventId(76), coreId(0)
    [C66xx_0] hostInt(11), eventId(77), coreId(0)
    [C66xx_0] hostInt(12), eventId(92), coreId(0)
    [C66xx_0] hostInt(13), eventId(93), coreId(0)
    [C66xx_0] hostInt(14), eventId(94), coreId(0)
    [C66xx_0] hostInt(15), eventId(95), coreId(0)
    [C66xx_0] hostInt(16), eventId(255), coreId(0)

    This host interrupt to event ID maps follows C6670 data sheet. Is this a bug of the software tool or I missed some configuration step?

    Dongning

     

     

  • Donging,

    If you don't already know this, this was a bug that has been fixed in SYSBIOS 6.32.04.49 and later.

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/sysbios/

    Judah