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.

TMS320C6678: IPC 多核通信,阻塞在messageQ_open.

Part Number: TMS320C6678
Other Parts Discussed in Thread: SYSBIOS

各种专家好,我找了一个多核通信的工程,单独跑工程没有问题,放到我的工程里就会阻塞在messageQ_open。

最终我对比发现是.cfg文件的问题。如果我使用 BIOS.heapsize =0x8000; 程序就能跑通。

如果指定 heap ,放在DDR上,程序就会阻塞。这是为什么?
rgb2gray_IPC.cfg

  • 这是cfg文件

    var Memory = xdc.useModule('xdc.runtime.Memory');
    var Log = xdc.useModule('xdc.runtime.Log');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Timestamp = xdc.useModule('xdc.runtime.Timestamp');
    var Startup = xdc.useModule('xdc.runtime.Startup');

    var hlink = xdc.useModule('ti.drv.hyplnk.Settings');

    var Swi = xdc.useModule('ti.sysbios.knl.Swi');
    var Timer = xdc.useModule('ti.sysbios.hal.Timer');
    var ti_sysbios_timers_timer64_Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
    var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');//0103
    var TimestampProvider = xdc.useModule('ti.sysbios.family.c64p.TimestampProvider');


    var System = xdc.useModule('xdc.runtime.System');
    var SysStd = xdc.useModule('xdc.runtime.SysStd');

    System.SupportProxy = SysStd;

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    //BIOS.heapSize = 0x8000;
    //BIOS.heapTrackEnabled = false;
    //BIOS.heapSection ="systemHeapMaster";
    //Program.sectMap["systemHeapMaster"] = new Program.SectionSpec();
    //Program.sectMap["systemHeapMaster"].loadSegment = "L2SRAM";

    //(Program.sectMap["systemHeapMaster"]="IPC")
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Sem = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var Ecm = xdc.useModule('ti.sysbios.family.c64p.EventCombiner');
    var BiosCache = xdc.useModule('ti.sysbios.hal.Cache');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var Exc = xdc.useModule('ti.sysbios.family.c64p.Exception');
    var Cache = xdc.useModule('ti.sysbios.family.c66.Cache');

    BIOS.taskEnabled = true;
    Task.common$.namedInstance = true;


    Ecm.eventGroupHwiNum[0] = 7;
    Ecm.eventGroupHwiNum[1] = 8;
    Ecm.eventGroupHwiNum[2] = 9;
    Ecm.eventGroupHwiNum[3] = 10;


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

    var Global = xdc.useModule('ti.ndk.config.Global');

    Global.enableCodeGeneration = false;
    var Ip = xdc.useModule('ti.ndk.config.Ip');
    var Tcp = xdc.useModule('ti.ndk.config.Tcp');

    var Csl = xdc.useModule('ti.csl.Settings');
    var Pa = xdc.useModule('ti.drv.pa.Settings');
    var Cppi = xdc.loadPackage('ti.drv.cppi');
    var Qmss = xdc.loadPackage('ti.drv.qmss');

    var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
    var nameList = MultiProc.getDeviceProcNames();
    MultiProc.setConfig(null, nameList);

    var Notify = xdc.useModule('ti.sdo.ipc.Notify');
    var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
    var Ipc = xdc.useModule('ti.sdo.ipc.Ipc');
    var HeapBufMP = xdc.useModule('ti.sdo.ipc.heaps.HeapBufMP');

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

    Ipc.procSync = Ipc.ProcSync_ALL;

    var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
    SharedRegion.numEntries = 4; // 最大共享区域的数目
    SharedRegion.translate = true; // 是否需要进行地址转换

    var SHAREDMEM = 0x0c000000;
    var SHAREDMEMSIZE = 0x00300000;

    SharedRegion.setEntryMeta(0,
    { base: SHAREDMEM,
    len: SHAREDMEMSIZE,
    ownerProcId: 0,
    isValid: true,
    name: "DDR2_RAM",
    });

    var Memory = xdc.useModule('xdc.runtime.Memory');
    Memory.defaultHeapSize = 0x10000;
    Program.heap = 0x10000;
    Program.sectMap[".vecs"] = {loadSegment: "L2SRAM", loadAlign:1024};
    Program.sectMap[".switch"] = {loadSegment: "L2SRAM", loadAlign:8};
    Program.sectMap[".cio"] = {loadSegment: "L2SRAM", loadAlign:8};
    Program.sectMap[".args"] = {loadSegment: "L2SRAM", loadAlign:8};
    Program.sectMap[".cppi"] = {loadSegment: "L2SRAM", loadAlign:16};
    Program.sectMap[".qmss"] = {loadSegment: "L2SRAM", loadAlign:16};
    Program.sectMap[".nimu_eth_ll2"] = {loadSegment: "L2SRAM", loadAlign:16};
    Program.sectMap[".far:NDK_PACKETMEM"]= {loadSegment: "DDR3", loadAlign: 128};
    Program.sectMap[".far:NDK_OBJMEM"] = {loadSegment: "DDR3", loadAlign: 16};
    /*Program.sectMap[".far:WEBDATA"] = {loadSegment: "DDR3", loadAlign: 8};*/
    Program.sectMap[".resmgr_memregion"] = {loadSegment: "L2SRAM", loadAlign:128};
    Program.sectMap[".resmgr_handles"] = {loadSegment: "L2SRAM", loadAlign:16};
    Program.sectMap[".resmgr_pa"] = {loadSegment: "L2SRAM", loadAlign:8};


    Program.sectMap["systemHeapMaster"] = "DDR3";
    Program.sectMap[".cinit"] = "L2SRAM";
    Program.sectMap[".const"] = "L2SRAM";
    Program.sectMap[".text"] = "DDR3";
    Program.sectMap[".far"] = "L2SRAM";
    Program.sectMap[".bss"] = "L2SRAM";
    Program.sectMap[".rodata"] = "L2SRAM";
    Program.sectMap[".neardata"] = "L2SRAM";
    Program.sectMap[".code"] = "L2SRAM";
    Program.sectMap[".data"] = "L2SRAM";
    Program.sectMap[".sysmem"] = "L2SRAM";
    Program.sectMap[".defaultStackSection"] = "L2SRAM";
    Program.sectMap[".stack"] = "L2SRAM";
    Program.sectMap[".plt"] = "L2SRAM";
    Program.sectMap["platform_lib"] = "L2SRAM";


    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    Program.global.semHandle = Semaphore.create(0);

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

    BIOS.libType = BIOS.LibType_Custom;

  • 如果使用定义heap程序,指定在DDR上就会阻塞在messageQ_opnen。

    如果不定义heap,设置默认heap,BIOS.heapsize =0x8000;程序就能跑通。

    结论是 heap只要在片上ram就行,只要放在DDR上就阻塞。片上ram 太小 我需要DDR空间,这该怎么办。

  • 请问跑的是自己的板子还是EVM板?

    多核通信的工程和自己的工程在合并前,heap放在ddr上,分别都能正常运行吗?

  • 1,分别都能能正常运行。

    2,我为了测试,不合并程序,在能正常运行的多核工程里直接改.cfg文件。 分别改heap位置, 对比发现是 heap的问题,放在DDR上就不行。

  • /*
    * ======== rgb2gray_IPC.c ========
    * 这是一个图像彩色转灰度的多核DSP程序
    * 这种程序将图像分为八块,C6678每个核操作其中一块图像
    * 主核(核0)将图像内存读入共享内存,各从核等待主核将内存读入后,开始处理任务
    * 当各从核完成图像块转换后,主核将数据存储,并完成内存释放
    */

    #include<xdc/std.h>
    #include<stdio.h>
    #include<stdlib.h>

    /* -----------------------------------XDC.RUNTIME module Headers */
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/hal/Cache.h>
    #include <xdc/runtime/Error.h>

    /* ----------------------------------- IPC module Headers */
    #include <ti/ipc/MultiProc.h>
    #include <ti/ipc/Notify.h>
    #include <xdc/runtime/IHeap.h>
    #include <ti/ipc/Ipc.h>
    /* ----------------------------------- BIOS6 module Headers */
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/BIOS.h>

    /* ----------------------------------- To get globals from .cfg Header */
    #include <xdc/cfg/global.h>
    #include <ti/ipc/MessageQ.h>
    #include <ti/ipc/HeapBufMP.h>
    #include <xdc/runtime/Memory.h>
    #include <ti/ipc/SharedRegion.h>

    #define INTERRUPT_LINE 0

    /* 定义颜色 */
    #define CV_BGR2GRAY 0

    /* 定义主核 */
    #define masterProc 0
    #define BufEVENT 10
    #define heapId 0

    #define coreNum 8
    #define dateNum 1*1024*1024 //12900 16 //8 //
    UInt16 recSlvNum = 0; // 表示主核接收到的从核回复次数

    UInt16 srcProc, dstProc;
    unsigned int *inBuf=NULL;
    unsigned int *outBuf=NULL;

    //String CoreName[8]={"MessageQ_Core0","MessageQ_Core1","MessageQ_Core2","MessageQ_Core3","MessageQ_Core4","MessageQ_Core5","MessageQ_Core6","MessageQ_Core7"};
    String CoreName[8]={"Core0","Core1","Core2","Core3","Core4","Core5","Core6","Core7"};

    typedef struct MyMsg {
    MessageQ_MsgHeader header;
    SharedRegion_SRPtr inBuf_SRPtr;
    SharedRegion_SRPtr outBuf_SRPtr;
    } MyMsg;

    MyMsg *msg; // 消息
    MessageQ_Handle messageQ; // 消息队列句柄 messageQ
    /*
    * ======== AcCvtColor ========
    * 这是一个图像RGB转换为灰度图像的程序
    * Image1是RGB图像,每个颜色通道为8位,三个颜色依次排列
    * Image2是灰度图像
    * coder表示转换模式,主要为以后扩展.
    */

    void AcCvtColor(unsigned char* image1,unsigned char* image2,int coder)
    {
    Int red,green,blue,gray;
    Int coreId=MultiProc_self();
    if(coder==CV_BGR2GRAY)
    {
    Int BlockSize=dateNum/coreNum;
    Int i;
    for(i=coreId*BlockSize;i<(coreId+1)*BlockSize;i++)
    {
    red=image1[i*3];
    green=image1[i*3+1];
    blue=image1[i*3+2];
    gray=(red*76+green*150+blue*30)>>8;
    image2[i]=(unsigned char)gray;
    }
    }
    }

    /*
    * ======== cbFxn ========
    * 这是Notify模块的注册函数
    * procId表示激动注册函数的核ID,或者说该事件是从哪个核来的
    */
    static UInt16 recCoreNum=0;
    Void cbFxn(UInt16 procId, UInt16 lineId,
    UInt32 eventId, UArg arg, UInt32 payload)
    {

    if(procId!=0)
    {
    recCoreNum++;
    if(recCoreNum==7)
    {
    recCoreNum =0;
    Semaphore_post(semHandle);
    }
    }else{
    Semaphore_post(semHandle);
    }
    }


    void fuction_active(int corenum)
    {

    SharedRegion_SRPtr inBuf_srptr; // 输入缓冲区在共享区域的指针
    SharedRegion_SRPtr outBuf_srptr; // 输出缓冲区在共享区域的指针
    Int i;

    if (corenum== 0) {
    // 分配内存
    IHeap_Handle heapshare = SharedRegion_getHeap(0);
    inBuf = (unsigned int*)Memory_alloc(heapshare, dateNum, 0, NULL);
    outBuf = (unsigned int*)Memory_alloc(heapshare, dateNum, 0, NULL);


    if(inBuf==NULL||outBuf==NULL)
    {
    System_printf("malloc Buf failed\n");
    BIOS_exit(0);
    }


    for(i=0;i<dateNum/4;i++)
    { // 这里dateNum=16
    outBuf[i]=i;
    }


    inBuf_srptr = SharedRegion_getSRPtr(inBuf, 0);
    outBuf_srptr = SharedRegion_getSRPtr(outBuf, 0);

    msg->inBuf_SRPtr = inBuf_srptr; // 消息打包
    msg->outBuf_SRPtr = outBuf_srptr;

    Cache_wbAll();// Write back all caches();

    //System_printf("finish msg config\n");
    System_printf("core%d inBuf address 0x%x ,outBuf address 0x%x\n",corenum,inBuf,outBuf);

    for(i=1;i<8;i++){ // 7个消息队列都需要发送消息
    MessageQ_QueueId sloverCoreQueueId;
    int status;
    do{ // 等待,直到打开MessageQ
    status= MessageQ_open(CoreName[i], &sloverCoreQueueId);
    if (status < 0)
    Task_sleep(1);
    }while (status < 0);
    status = MessageQ_put(sloverCoreQueueId, (MessageQ_Msg)msg);
    if (status < 0)
    System_abort("MessageQ_put was not successful\n");

    do{ // 等待,直到关闭MessageQ
    status= MessageQ_close(&sloverCoreQueueId);
    if (status < 0)
    Task_sleep(1);
    }while (status < 0);
    }

    Cache_disable(Cache_Type_ALL);

    //AcCvtColor(inBuf,outBuf,CV_BGR2GRAY); // 分核完成图像灰度转换任务

    Cache_wbAll(); // Write back all caches();

    Semaphore_pend(semHandle, BIOS_WAIT_FOREVER); // 等待从核完成全部任务

    Cache_inv(outBuf,sizeof(outBuf),Cache_Type_ALL,TRUE);//刷新结果所在的内存
    Cache_wait();

    //System_printf("outBuf date is ");
    for(i=0;i<dateNum/4;i++)
    {
    if(outBuf[i]!=i)
    {
    System_printf("cache er %d , %d ",outBuf[i],i);
    break;
    }
    }
    /*for(i=0;i<dateNum;i++)
    System_printf("%d ",outBuf[i]);
    System_printf("\n");
    */


    for(i=1;i<8;i++)
    Notify_sendEvent(i, INTERRUPT_LINE, BufEVENT, 0, TRUE);


    Memory_free(heapshare,inBuf, dateNum);
    Memory_free(heapshare,outBuf, dateNum);

    }else{

    int status = MessageQ_get(messageQ, (MessageQ_Msg *)&msg, MessageQ_FOREVER);
    if (status < 0)
    System_abort("This should not happen since timeout is forever\n");
    inBuf_srptr = msg->inBuf_SRPtr;
    outBuf_srptr = msg->outBuf_SRPtr;

    System_printf("MessageQ get is finished \n");

    Cache_disable(Cache_Type_ALL);

    /*
    status = MessageQ_free((MessageQ_Msg)msg);
    if (status < 0)
    System_abort("Message free failed\n");

    System_printf("MessageQ free is finished \n");
    */

    /*
    status = MessageQ_delete(&messageQ);
    if (status < 0)
    System_abort("MessageQ delete failed\n");

    System_printf("MessageQ delete is finished \n");
    */

    inBuf = SharedRegion_getPtr(inBuf_srptr);
    outBuf = SharedRegion_getPtr(outBuf_srptr);

    System_printf("core%d inBuf address 0x%x ,outBuf address 0x%x\n",corenum,inBuf,outBuf);


    for(i=0;i<dateNum/4;i++)
    {
    if(outBuf[i]!=i)
    {
    System_printf("cache er %d , %d ",outBuf[i],i);
    break;
    }
    }

    //AcCvtColor(inBuf,outBuf,CV_BGR2GRAY); // 分核完成图像灰度转换任务

    Cache_wbAll(); // Write back all caches();

    // Write back all caches();
    status = Notify_sendEvent(0, INTERRUPT_LINE, BufEVENT, 0, TRUE);

    //System_printf("core%d sendEvent finished,status is %d\n",coreId,status);
    if (status < 0) {
    System_abort("sendEvent to MasterCore failed\n");
    }

    Semaphore_pend(semHandle, BIOS_WAIT_FOREVER); // 等待从核完成全部任务
    }

    }
    void massageheap_ini(int corenum)
    {
    int i=0;
    MessageQ_Params messageQParams; // 消息队列参数

    HeapBufMP_Handle heapHandle; // 堆句柄
    HeapBufMP_Params heapBufParams; // 堆参数

    if (corenum != 0){ // 从核,创建消息队列
    for(i=0;i<1000000*corenum;i++);
    MessageQ_Params_init(&messageQParams);
    messageQ = MessageQ_create(CoreName[corenum], &messageQParams);
    if(messageQ==NULL)
    System_printf("MessageQ core%d create is failed \n",corenum);
    //System_printf("MessageQ core%d create is finished %s\n",corenum);
    }else{
    // 创建堆,给消息分配空间
    HeapBufMP_Params_init(&heapBufParams);
    heapBufParams.regionId = 0;
    heapBufParams.name = "Msg_Heap";
    heapBufParams.numBlocks = 1; // 1个块
    heapBufParams.blockSize = sizeof(MyMsg); // 块的大小刚好是一个消息长度
    heapHandle = HeapBufMP_create(&heapBufParams);
    if (heapHandle == NULL) {
    System_abort("HeapBufMP_create failed\n" );
    }

    int status = MessageQ_registerHeap(heapHandle,heapId);
    if (status == MessageQ_E_ALREADYEXISTS){
    System_abort("heap already exists with heapId\n" );
    }
    // System_printf("MessageQ registerHeap finished\n");
    msg = (MyMsg*)MessageQ_alloc(heapId, sizeof(MyMsg));
    if (msg == NULL) {
    System_abort("MessageQ_alloc failed\n");
    }
    System_printf("MessageQ alloc finished\n");
    }
    }

    /*
    * ======== tsk0_func ========
    * Sends an event to the next processor then pends on a semaphore.
    * The semaphore is posted by the callback function.
    */

    void SemaphoreIni(Semaphore_Handle *Semaphoretmp,int inicnt)
    {
    Error_Block eb;
    Semaphore_Params params;
    Error_init(&eb);
    Semaphore_Params_init(&params);
    params.mode=Semaphore_Mode_BINARY;

    *Semaphoretmp= Semaphore_create(inicnt, &params, &eb);
    }

    Void tsk0_func(UArg arg0, UArg arg1)
    {
    Semaphore_Handle Semaphoretmp;
    SemaphoreIni(&Semaphoretmp,1);

    int CoreId=MultiProc_self();

    massageheap_ini(CoreId);
    while(1)
    {
    //Semaphore_pend(semHandle, 500); // 等待从核完成全部任务
    System_printf("test start ci%d\n",CoreId);
    fuction_active(CoreId);
    System_printf("test end ci%d\n",CoreId);
    }

    }

    /*
    * ======== main ========
    * Synchronizes all processors (in Ipc_start), calls BIOS_start, and registers
    * for an incoming event
    */
    Int main(Int argc, Char* argv[])
    {
    Int status;

    /*
    * Ipc_start() calls Ipc_attach() to synchronize all remote processors
    * because 'Ipc.procSync' is set to 'Ipc.ProcSync_ALL' in *.cfg
    */
    status = Ipc_start();
    if (status < 0) {
    System_abort("Ipc_start failed\n");
    }

    if (MultiProc_self() == 0)
    {
    Int i;
    for(i=1;i<8;i++)
    status = Notify_registerEvent(i, INTERRUPT_LINE, BufEVENT,(Notify_FnNotifyCbck)cbFxn, NULL);
    }
    else
    {
    // 从核完成事件注册
    status = Notify_registerEvent(0, INTERRUPT_LINE, BufEVENT,(Notify_FnNotifyCbck)cbFxn, NULL);

    System_printf("registerEvent status is %d\n",status);

    }

    BIOS_start();

    return (0);
    }

  • 自己的板子,不是EVM板。

  • 2,我为了测试,不合并程序,在能正常运行的多核工程里直接改.cfg文件。 分别改heap位置, 对比发现是 heap的问题,放在DDR上就不行。

    不合并程序,多核工程里heap位置改到DDR上也不行是么?

  • 是的,heap 只要放在DDR就不行。放在DDR,1种现象是,核0阻塞在messageQ_open位置,核1-7正常。2还有种情况,有的时候 核1-7还跑飞,直接abort。

  • 程序就我贴出来的这些,没问题吧。难道是DDR有问题?

  • 请问有尝试过把代码放在DDR上跑吗?如果能稳定运行的话,可以排除DDR的问题。

  • //Memory.defaultHeapInstance = Program.global.systemHeapMaster;

    屏蔽这句话 好使了。

  • 把下面的systemHeapMaster不要与heapMemParams.sectionName = "systemHeapMaster";重名。
    Program.global.systemHeapMaster = HeapMem.create(heapMemParams);
    Memory.defaultHeapInstance = Program.global.systemHeapMaster;

    改成其他的如myheap试试
    Program.global.myheap= HeapMem.create(heapMemParams);
    Memory.defaultHeapInstance = Program.global.myheap;

    看一下下面的文档。
    5.3 Heaps
    https://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/sysbios/6_30_02_42/exports/docs/docs/Bios_Legacy_App_Note.pdf


  • 1,目前 还是有问题,只要用网络的task就不行,还是会卡死。

    2,6678的多核开发,对bios  ndk  pdk  ipc 版本有没有最低的限制。

    我用的 1,ccs 5.5 ;

    2,ipc 1.24.3.32

    3,MSDK 1.1.2.6

    4,NDK 2.22.3.20

    5,SYS/bios 6.33.6.50

  • SDK软件包里一般包含了bios  ndk  pdk  ipc。可以看一下release note对各个软件版本的要求。