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.

IPC MessageQ problems on F28M35x

Greetings all...

I'm working on using the MessageQ on the Concerto between the C28 and the M3 (in that direction only).

My system uses:

Code Composer Studio Version: 5.2.0.00070
SYS\Bios 6.33.5.46
IPC  1.24.3.32
XDC Tools 3.23.3.53 

When trying to run the messageQ sample in the sys\bios wizard, everything works great but when I use it in my program, the moment I call "MessageQ_put" over the C28, I get an exception over the M3 as following:

[Cortex_M3_0] ti.sdo.ipc.MessageQ: line 132: assertion failure: A_heapIdInvalid: heapId is invalid
[Cortex_M3_0] xdc.runtime.Error.raise: terminating execution

Here is the code (It won't compile, didn't want to bore you with my code)
The code in the C28 is:

Bool InitMessageQ(Void)
{
Ptr buf;
SizeT blockSize;
UInt numBlocks;
Int32 status;
// Compute the blockSize & numBlocks for the HeapBuf
numBlocks = 1;
int mult = (int)(ceil((float)sizeof(RESULTS_MESSAGE) / sizeof(MessageQ_MsgHeader)));
blockSize = sizeof(MessageQ_MsgHeader) * mult;
// Alloc a buffer from the default heap
buf = Memory_alloc(0, numBlocks * blockSize, 0, NULL);
// Create the heap that is used for allocating MessageQ messages.
HeapBuf_Params_init(&hbparams);
hbparams.align = 0;
hbparams.numBlocks = numBlocks;
hbparams.blockSize = blockSize;
hbparams.bufSize = numBlocks * blockSize;
hbparams.buf = buf;
heapHandle = HeapBuf_create(&hbparams, NULL);
if (heapHandle == NULL) {
System_printf("HeapBuf_create failed\n" );
return FALSE;
}
// Register default system heap with MessageQ
MessageQ_registerHeap((IHeap_Handle)(heapHandle), HEAPID);
// Open the remote message queue. Spin until it is ready.
do {
status = MessageQ_open(remoteQueueName, &remoteQueueId);
// Sleep for 1 clock tick to avoid inundating remote processor
// with interrupts if open failed
if (status < 0) {
Task_sleep(1);
}
} while (status < 0);
/* Allocate a message to be ping-ponged around the processors */
/*msg = MessageQ_alloc(HEAPID, sizeof(RESULTS_MESSAGE));
if (msg == NULL) {
System_printf("MessageQ_alloc failed\n" );
return FALSE;
}*/
return TRUE;
}

void task0()
{
InitMessageQ();
  bla bla...
semaphore wait...

/* Allocate a message to be ping-ponged around the processors */
msg = MessageQ_alloc(HEAPID, sizeof(RESULTS_MESSAGE));
if (msg != NULL)
{
res = PR_DETECTION;
PopulateMsg(((RESULTS_MESSAGE*)msg), reg_counter, Sblobs);
status = MessageQ_put(remoteQueueId, msg);
if (status < 0) {
System_printf("MessageQ_put had a failure/error\n");
}
}


The code over the M3 is:

Bool InitMessageQ(Void)
{
Ptr buf;
SizeT blockSize;
UInt numBlocks;
/* Compute the blockSize & numBlocks for the HeapBuf */
numBlocks = 1;
int mult = (int)(ceil((float)sizeof(RESULTS_MESSAGE) / sizeof(MessageQ_MsgHeader)));
blockSize = sizeof(MessageQ_MsgHeader) * mult;
/* Alloc a buffer from the default heap */
buf = Memory_alloc(0, numBlocks * blockSize, 0, NULL);
/*
* Create the heap that is used for allocating MessageQ messages.
*/
HeapBuf_Params_init(&hbparams);
hbparams.align = 0;
hbparams.numBlocks = numBlocks;
hbparams.blockSize = blockSize;
hbparams.bufSize = numBlocks * blockSize;
hbparams.buf = buf;
heapHandle = HeapBuf_create(&hbparams, NULL);
if (heapHandle == NULL) {
System_printf("HeapBuf_create failed\n" );
return FALSE;
}
/* Register default system heap with MessageQ */
MessageQ_registerHeap((IHeap_Handle)(heapHandle), HEAPID);
/* Create the local message queue */
messageQ = MessageQ_create(localQueueName, NULL);
if (messageQ == NULL) {
System_printf("MessageQ_create failed\n" );
return FALSE;
}
return TRUE;
}
void task0()
{
InitMessageQ()
bla bla...
semaphor wait...
status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
if (status == MessageQ_S_SUCCESS)
{
RESULTS_MESSAGE* m = (RESULTS_MESSAGE*)msg;
Short msgId = MessageQ_getMsgId(msg);
msgId++;
}

 

My struct is:

typedef struct RESULTS_MSG_ST {
MessageQ_MsgHeader header; // Required
Short blobsCount;
PROCESSING_RESULT blobsResult[MAX_BLOB_N * 2];
} RESULTS_MESSAGE;

 

cfg file:

var BIOS = xdc.useModule('ti.sysbios.BIOS');
var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
var Boot = xdc.useModule('ti.catalog.arm.cortexm3.concertoInit.Boot');
var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
var Timestamp = xdc.useModule('xdc.runtime.Timestamp');
MultiProc.setConfig("M3", ["M3", "C28"]);
/* 
* 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;
/* Task that does the notify sending */
var Task = xdc.useModule('ti.sysbios.knl.Task');
var tsk0 = Task.create('&tsk0_func');
tsk0.instance.name = "tsk0";
/* Modules explicitly used in the application */
/*var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');*/
/* Use the f28m35x IpcMgr to configure the shared buffers used by IPC */
var IpcMgr = xdc.useModule('ti.sdo.ipc.family.f28m35x.IpcMgr');
IpcMgr.readAddr = 0x2007F000;
IpcMgr.writeAddr = 0x2007F800;
/* 
* The M3 has to grant write access to the shared memory that the C28 will be
* writing to.
*/
IpcMgr.sharedMemoryOwnerMask = 0x90;
IpcMgr.sharedMemoryAccess[4] = 1;
IpcMgr.sharedMemoryAccess[7] = 1;
/* Create a semaphore with count 0 */
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
var semHandleParams = new Semaphore.Params();
semHandleParams.instance.name = "semHandle";
semHandleParams.eventId = 10;
Program.global.semHandle = Semaphore.create(0, semHandleParams);
/* Create a semaphore with count 1 */
var semLeftParams = new Semaphore.Params();
semLeftParams.instance.name = "semLeft";
semLeftParams.eventId = 11;
Program.global.semLeft = Semaphore.create(1, semLeftParams);
var task1Params = new Task.Params();
task1Params.instance.name = "tsk1";
Program.global.tsk1 = Task.create("&tsk1_func", task1Params);
Program.stack = 2048;

Why the hell is this happening?

Anyone encountered this problem before?

Appreciate the help...

Yoel

  • Hi,

    I think that the problem is because you're creating the heap and the messageQ in a function (InitMessageQ) and trying to access them from the task.

    If you look at the MessageQ.c file - line 132 the error message you got occurs when:

    127 MessageQ_Msg MessageQ_alloc(UInt16 heapId, Uint32 size)
    128 {
    129     MessageQ_Msg msg;
    130     Error_Block eb;
    131
    132     Assert_isTrue((heapId < MessageQ_module->numHeaps), ti_sdo_ipc_MessageQ_A_heapIdInvalid);

    You could try changing the InitMessageQ function or the task0 (I don't know how).

    Regards

  • Hey,

    Thanks for the reply.

    The function is only there so the code will be more readable, even tough, I tried moving all the code to the task but the exception keep comming.

    By the way, the size of my struct is 76Bytes on the M3 and 38Bytes (x 2) on the C28.

    The messageQ max size is 128Bytes so I don't think that this is the problem.

  • Can you put a breakpoint on the MessageQ_put() call o the sender side and look at the MessageQ_Header fields?   One of the fields in this structure should be the 'heapId' field which should match the 'HEAPID' value in your code.  Maybe this field is somehow getting corrupted between the alloc() call and the put() call.

    HEAPID must match on both cores, but it looks like you have that OK.

    If this doesn't help, can you zip up a test case and attache it here so that someone can build it and take a look?

    /*!
     *  @brief      Required first field in every message
     */
    typedef struct {
        Bits32       reserved0;         /*!< reserved for List.elem->next       */
        Bits32       reserved1;         /*!< reserved for List.elem->prev       */
        Bits32       msgSize;           /*!< message size                       */
        Bits16       flags;             /*!< bitmask of different flags         */
        Bits16       msgId;             /*!< message id                         */
        Bits16       dstId;             /*!< destination queue id               */
        Bits16       dstProc;           /*!< destination processor id           */
        Bits16       replyId;           /*!< reply id                           */
        Bits16       replyProc;         /*!< reply processor                    */
        Bits16       srcProc;           /*!< source processor                   */
        Bits16       heapId;            /*!< heap id                            */
        Bits16       seqNum;            /*!< sequence number                    */
        Bits16       reserved;          /*!< reserved                           */
    } MessageQ_MsgHeader;

  • Hey Guys,

    Apparently the problem was cased by a memory overrun because of a buffer overflow.

    The MessageQ module members where located right after that buffer in the memory.

    The HeapID was fine in the sender but was corrupted on the receiving end.

    Thanks for the help!