Other Parts Discussed in Thread: SYSBIOS
各种专家好,我找了一个多核通信的工程,单独跑工程没有问题,放到我的工程里就会阻塞在messageQ_open。
最终我对比发现是.cfg文件的问题。如果我使用 BIOS.heapsize =0x8000; 程序就能跑通。
如果指定 heap ,放在DDR上,程序就会阻塞。这是为什么?
rgb2gray_IPC.cfg
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.
各种专家好,我找了一个多核通信的工程,单独跑工程没有问题,放到我的工程里就会阻塞在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;
/*
* ======== 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(¶ms);
params.mode=Semaphore_Mode_BINARY;
*Semaphoretmp= Semaphore_create(inicnt, ¶ms, &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);
}
2,我为了测试,不合并程序,在能正常运行的多核工程里直接改.cfg文件。 分别改heap位置, 对比发现是 heap的问题,放在DDR上就不行。
不合并程序,多核工程里heap位置改到DDR上也不行是么?
把下面的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