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.

C6670 IPC_start多核同步的问题



大家好,

我的工程中IPC的配置为

Ipc.procSync = Ipc.ProcSync_ALL;

MultiProc.setConfig(null, ["CORE0", "CORE1", "CORE2", "CORE3"]);

for (var i = 0; i < MultiProc.numProcessors; i++) {
Ipc.setEntryMeta({
remoteProcId: i,
setupNotify: true,
setupMessageQ: false,
});
}

每个CORE的代码都运行IPC_Start();

然后依次加载4个CORE的程序,从CORE0到CORE3。

遇到的问题是:CORE3的SYS/BIOS任务能够正常运行,但是CORE0~2的SYS/BIOS任务跑不起来,如下图

CORE0~CORE2都死循环在singlecore_osal.c的下面的代码第7行处了

PtrOsal_cppiCsEnter (Void)
{
/* Get the hardware semaphore. 
     *
     * Acquire Multi core CPPI synchronization lock 
     */
while ((CSL_semAcquireDirect (CPPI_HW_SEM)) == 0);

/* Disable all interrupts and OS scheduler. 
     *
     * Acquire Multi threaded / process synchronization lock.
     */
coreKey [CSL_chipReadReg (CSL_CHIP_DNUM)] = Hwi_disable();

return NULL;
}

 

感觉是IPC_Start();没有完成4个核之间的 processor synchronization。

*********************************************************************************************************

但是如果我改代码为如下

MultiProc.setConfig(null, ["CORE0", "CORE1");

然后只加载CORE0和CORE1的代码。步骤为:

1.先加载CORE0代码。CORE0卡在IPC_Start();

2.然后再加载CORE1代码,CORE1 SYS/BIOS跑起来了。

3.接着CORE0的SYS/BIOS也跑起来了,一切正常。

*********************************************************************************************************

就是当我打算调试4个核心的时候,问题就出来了。

调3个核也有这样的问题

*********************************************************************************************************

望大家给予帮助!!多谢!!

  • 看你提示不太像卡在ipc start,我导入pdk中的IPC例程,如C:\ti\pdk_C6670_1_1_2_6\packages\ti\transport\ipc\examples\qmssIpcBenchmark ,修改为4core IPC同步,可以正常运行,IPC的配置在cfg文件中,与你的类似,参考一下例子。

  • **************************************************************************************************

    您好!我又调试了一下,确实如您所说,并不是卡在IPC_start()处。现在我的问题更新如下:

    **************************************************************************************************

    我的SRIO配置代码如下:

    UInt8           isAllocated;
    Srio_DrvConfig  drvCfg;
    
    System_printf ("Core Num = %d\n", corenum);
    
    /* Initialize the SRIO Driver Configuration. */
    memset ((Void *)&drvCfg, 0, sizeof(Srio_DrvConfig));
    
    /* Initialize the OSAL */
    if (Osal_dataBufferInitMemory(SRIO_MAX_MTU) < 0)
    {
    	System_printf ("Error: Unable to initialize the OSAL. \n");
    	return -1;
    }
    
    /********************************************************************************
     * The SRIO Driver Instance is going to be created with the following properties:
     * - Driver Managed
     * - Interrupt Support (Pass the Rx Completion Queue as NULL)
     ********************************************************************************/
    /* Setup the SRIO Driver Managed Configuration. */
    drvCfg.bAppManagedConfig = FALSE;
    
    /* Driver Managed: Receive Configuration */
    drvCfg.u.drvManagedCfg.bIsRxCfgValid             = 1;
    drvCfg.u.drvManagedCfg.rxCfg.rxMemRegion         = Qmss_MemRegion_MEMORY_REGION1;//Qmss_MemRegion_MEMORY_REGION1;//Qmss_MemRegion_MEMORY_REGION0
    drvCfg.u.drvManagedCfg.rxCfg.numRxBuffers        = 4;
    drvCfg.u.drvManagedCfg.rxCfg.rxMTU               = SRIO_MAX_MTU;
    
    /* Accumulator Configuration. */
    {
    	int32_t coreToQueueSelector[4];
    
      /* This is the table which maps the core to a specific receive queue. */
    	coreToQueueSelector[0] = 736;//736;//704
    	coreToQueueSelector[1] = 737;
    	coreToQueueSelector[2] = 738;
    	coreToQueueSelector[3] = 739;
    
    	/* Since we are programming the accumulator we want this queue to be a HIGH PRIORITY Queue */
    	drvCfg.u.drvManagedCfg.rxCfg.rxCompletionQueue = Qmss_queueOpen (Qmss_QueueType_HIGH_PRIORITY_QUEUE,
    																	 coreToQueueSelector[corenum], &isAllocated);
    	System_printf ("Test Point 4\n");
    
    	if (drvCfg.u.drvManagedCfg.rxCfg.rxCompletionQueue < 0)
    	{
    		System_printf ("Error: Unable to open the SRIO Receive Completion Queue\n");
    		return 0;
    	}
    
    	/* Accumulator Configuration is VALID. */
    	drvCfg.u.drvManagedCfg.rxCfg.bIsAccumlatorCfgValid = 1;
    
    	/* Accumulator Configuration. */
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.channel             = corenum+16;//corenum;//1
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.command             = Qmss_AccCmd_ENABLE_CHANNEL;
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.queueEnMask         = 0;
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.queMgrIndex         = coreToQueueSelector[corenum];
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.maxPageEntries      = 2;
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.timerLoadCount      = 0;
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.interruptPacingMode = Qmss_AccPacingMode_LAST_INTERRUPT;
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.listEntrySize       = Qmss_AccEntrySize_REG_D;
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.listCountMode       = Qmss_AccCountMode_ENTRY_COUNT;
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.multiQueueMode      = Qmss_AccQueueMode_SINGLE_QUEUE;//Qmss_AccQueueMode_SINGLE_QUEUEQmss_AccQueueMode_MULTI_QUEUE
    
    	/* Initialize the accumulator list memory */
    	memset ((Void *)&gHiPriAccumList0[corenum], 0, sizeof(gHiPriAccumList0));
    	drvCfg.u.drvManagedCfg.rxCfg.accCfg.listAddress = l2_global_address((UInt32)&gHiPriAccumList0[corenum]);
    }
    /* Driver Managed: Transmit Configuration */
    drvCfg.u.drvManagedCfg.bIsTxCfgValid             = 1;
    drvCfg.u.drvManagedCfg.txCfg.txMemRegion         = Qmss_MemRegion_MEMORY_REGION1;//Qmss_MemRegion_MEMORY_REGION0
    drvCfg.u.drvManagedCfg.txCfg.numTxBuffers        = 4;
    drvCfg.u.drvManagedCfg.txCfg.txMTU               = SRIO_MAX_MTU;
    
    /* Start the Driver Managed SRIO Driver. */
    hDrvManagedSrioDrv = Srio_start(&drvCfg);
    if (hDrvManagedSrioDrv == NULL)
    {
    	System_printf ("Error(Core %d): SRIO Driver failed to start\n", corenum);
    	return -1;
    }

    这样的配置代码,每个Core都跑一下。

    如果不在main函数中,BIOS_Start()之前添加IPC_start(),代码运行在4个Core上都没有问题,4个Core都能正常地对外发送SRIO SWRITE包等。

    但是,如果在main函数中,BIOS_Start()之前添加IPC_Start(),从core0到core3依次加载该代码,发现只有Core3的SRIO task能正常起来,然而Core0~Core2都卡在

    hDrvManagedSrioDrv = Srio_start(&drvCfg);

    这里了!实际暂停Debug Core0~Core2时,发现Core0~Core2都卡在

    PtrOsal_cppiCsEnter (Void)
    {
    /* Get the hardware semaphore. 
         *
         * Acquire Multi core CPPI synchronization lock 
         */
    while ((CSL_semAcquireDirect (CPPI_HW_SEM)) == 0);
    
    /* Disable all interrupts and OS scheduler. 
         *
         * Acquire Multi threaded / process synchronization lock.
         */
    coreKey [CSL_chipReadReg (CSL_CHIP_DNUM)] = Hwi_disable();
    
    return NULL;
    }

    第7行!!

    我查了一下,大致可能是由于SRIO、CPPI的LLD中的OSAL代码包含了一些信号量操作,用于在多核间同步时进行critical section维护,还是别的什么的。

    **************************************************************************************************

    我想问的是:

    1. 这种问题应该怎么解决?或者从何入手解决?

    2. CPPI、SRIO LLD中的OSAL层有更多的可参考的文档吗?涉及为什么要进行信号量操作去维护一个shared resource?而我遇到了CPPI的信号量一直accuqire不到,可能在什么地方发送了冲突?

    3. 为什么CPPI_HW_SEM的值为4,哪个文档中指明了semaphore2的第4个信号量是针对CPPI的?我看了semaphore2的文档,其64个信号量应该都已一样的。这里的CPPI_HW_SEM的值为4,只是一种实现,如果为5,也行?

    4. 为什么我不添加IPC_start()就行,添加了IPC_start()就出问题了?

    5. 而且如果我添加了IPC_start(),只在两个Core上跑程序,也没有问题,核间IPC Notify正常、SRIO发包正常,但是运行在3个或者4个Core上就出问题了。

    **************************************************************************************************

    谢谢!希望您不吝赐教!!

  • 您好!

    我的整个工程为

    烦您有时间帮我看一下!

    ****************************************************************************************************************

    我想实现的就是4个Core能够同时对外发送SWRITE包,并且核间能够实现IPC Notify通信。

    遇到的问题就是如工程中loopbackDioIsr.c的第710行

    1.注释掉IPC_Start(),4个Core能够同时对外发送SWRITE包

    2.加上IPC_Start(),只有Core3能正常运行SRIO的task dioExampleTask,而Core0~Core2都卡在了

    hDrvManagedSrioDrv = Srio_start(&drvCfg);

    并且此时暂停Debug Core0~Core2的话,Core0~Core2是停在singlecore_osal.c文件中的

    Ptr Osal_cppiCsEnter (Void)
    {
        /* Get the hardware semaphore. 
         *
         * Acquire Multi core CPPI synchronization lock 
         */
        while ((CSL_semAcquireDirect (CPPI_HW_SEM)) == 0);
    
        /* Disable all interrupts and OS scheduler. 
         *
         * Acquire Multi threaded / process synchronization lock.
         */
        coreKey [CSL_chipReadReg (CSL_CHIP_DNUM)] = Hwi_disable();
    
        return NULL;
    }

    第7行!

    ****************************************************************************************************************

    非常感谢!!

  • 大家好,

    我遇到的问题见http://www.deyisupport.com/question_answer/dsp_arm/c6000_multicore/f/53/p/69770/167563.aspx#167563,整个工程在4楼。

    大致描述我的问题是:

    原工程包含了SRIO代码,在我们的板卡上运行正常。而后打算添加IPC实现核间通讯。

    但是在原来的SRIO代码上添加IPC_start(),然后加载代码到4个Core上,发现只有Core3的SRIO Task起来了,而Core0~Core2都挂在了

    原来SRIO工程中singlecore_osal.c

    Ptr Osal_cppiCsEnter (Void)
    {
        /* Get the hardware semaphore. 
         *
         * Acquire Multi core CPPI synchronization lock 
         */
        while ((CSL_semAcquireDirect (CPPI_HW_SEM)) == 0);
    
        /* Disable all interrupts and OS scheduler. 
         *
         * Acquire Multi threaded / process synchronization lock.
         */
        coreKey [CSL_chipReadReg (CSL_CHIP_DNUM)] = Hwi_disable();
    
        return NULL;
    }
    第7行!

    Core0~Core2的SRIO task在执行

    hDrvManagedSrioDrv = Srio_start(&drvCfg);

    时进行了OSAL的一些操作,然后产生了以上的错误。

    感觉是IPC在运行时会申请信号量CPPI_HW_SEM,结果原SRIO工程的CPPI OSAL也申请了这个信号量,所以产生了冲突。

    不知道我理解的对不对??

    想问的是:

    1. IPC具体申请了哪些信号量,可否禁止?

    2. 原SRIO工程为什么要跑CPPI OSAL,不跑可以吗?

    谢谢!!~

  • "如果不在main函数中,BIOS_Start()之前添加IPC_start(),代码运行在4个Core上都没有问题,4个Core都能正常地对外发送SRIO SWRITE包等。

    但是,如果在main函数中,BIOS_Start()之前添加IPC_Start(),从core0到core3依次加载该代码,发现只有Core3的SRIO task能正常起来,然而Core0~Core2都卡在"

    上面这段话是什么意思,跟IPC_start调用的位置有关么?

    IPC模块中没有使用硬件semaphore,你可以检查Semaphore的状态寄存器,看看此时这个信号量被哪个master占用了。相关的osal函数的调用是为了对共享资源的互斥,保证某一个时刻只有一个master访问。

  • 是我表述的有问题!

    您引用的那句话,我想表达的是“如果不添加IPC_Start()代码正常,Core0~Core3上的SRIO task都能跑起来;但是添加IPC_start()后,只有Core3的SRIO Task起来了,然而Core0~Core2卡住了”

    1. 上述的Ptr Osal_cppiCsEnter (Void)是在什么时候被调用的?为什么不添加IPC的时候没有问题,而添加了IPC就出现了问题?

    2. 上述Ptr Osal_cppiCsEnter (Void)中的while ((CSL_semAcquireDirect (CPPI_HW_SEM)) == 0);为什么要通过Direct的方式去acquire信号量4(CPPI_HW_SEM的宏定义值为4),而不是其他信号量?信号量4跟CPPI有关系吗?