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 problem with ARM & DSP

Other Parts Discussed in Thread: SYSBIOS

Hi all,

I've implemented MessageQ communication between the ARM and DSPs exactly like in the image processing demo source code.

I've faced the following problem:

1. I send a message to each DSP core in a row 

2. These messages are received correctly on each DSPs

3. the same message is send back immediately to ARM's MessageQueue

=> Only 1-2 messages are received back on the ARM side ( varies)

* If I sleep on each DSP core fixed time (10 ms on core 0, 20 ms on core 1, 30 ms on Core 2, etc..), than ALL messages are received correctly on the ARM side.

* I tried to put a semaphore around MessageQ_put(replyQueueId, msg) on DSP, but it didn't help.

Do I need a synchronizer on the host MessageQ? What is the default synchoronizer on Linux side on the MessageQ, if I call  create function with null parameter: MessageQ_create(MPU_MESSAGEQNAME, NULL);

  • Few additional remarks:

    - it seems that Linux side MessageQ can hold only one message. When I make sure that there is only one message at the time, it works all the time.

    - when I call  MessageQ_count(g_ddrMsgHandle); it returns -1, which indicates of some error (on DSP side, the count returns zero when there are no messages on the Queue).

    => I suspect that I'm missing some configuration/initialization with IPC/MessageQ. 

    However, I'm doing all same steps that are in the Image processing Demo.

    ----------------------

    So, bottom line question is: why I cannot put more than one message in IPC/MessageQ on ARM/Linux side queue?

  • YES! YES! YES! Found the problem!

    It is in MessageQ_get() function (Linux impl.): https://git.ti.com/ipc/ipcdev/blobs/master/linux/src/api/MessageQ.c

    There is missing a break statement after a message is found. If all cores have sent a message when get is called, it returns only the last one.

                for (rprocId = 0; rprocId < MultiProc_getNumProcessors();
                     rprocId++) {
                    if (rprocId == MultiProc_self()) {
                        continue;
                    }
                    if (FD_ISSET(obj->fd[rprocId], &rfds)) {
                        /* Our transport's fd was signalled: Get the message: */
                        tmpStatus = transportGet(obj->fd[rprocId], msg);
                        if (tmpStatus < 0) {
                            printf ("MessageQ_get: tranposrtshm_get failed.");
                            status = MessageQ_E_FAIL;
                        }
                    }
                }

    Does someone know what is the formal way to get the IPC development team aware of this bug & fix?

  • Thanks! We'll have developer to look into it.

     

  • Vesa Peltonen said:
    So, bottom line question is: why I cannot put more than one message in IPC/MessageQ on ARM/Linux side queue?

    How many MessageQ buffers are you allocating (e.g. MessageQ_alloc)?  Your allocs will determine the max number of messages that can be put on the queue. This may be the source of your issue.

    Take a look at the IPC User's Guide MessageQ section for more info on the module:

    http://processors.wiki.ti.com/index.php/IPC_User%27s_Guide/MessageQ_Module

    I haven't looked at the code in detail to determine if in fact there is a bug or just mis-use of the MessageQ APIs but IPC development is open source and anyone is free to submit fixes.  Take a look at the IPC development  wiki page for some info:

    http://git.ti.com/ipc/pages/Home

    You can also just post your issues on TI's E2E Embedded Software Forums in either Linux and/or Ti-RTOS (aka SysBios) since IPC supports both those OSes.

  • Vesa,

    Excellent work finding that problem, it does indeed look like the cause of your issue.

    Vesa Peltonen said:

    There is missing a break statement after a message is found. If all cores have sent a message when get is called, it returns only the last one.

    We will fix this as you said, shown here (new code in red):

     for (rprocId = 0; rprocId < MultiProc_getNumProcessors(); rprocId++) { if (rprocId == MultiProc_self()) { continue; } if (FD_ISSET(obj->fd[rprocId], &rfds)) { /* Our transport's fd was signalled: Get the message: */ tmpStatus = transportGet(obj->fd[rprocId], msg); if (tmpStatus < 0) { printf ("MessageQ_get: tranposrtshm_get failed."); status = MessageQ_E_FAIL;                     }
                        break;
     } }

    Vesa Peltonen said:

    Does someone know what is the formal way to get the IPC development team aware of this bug & fix?

    This forum is the correct way to alert the IPC development team.  You could also report it to the 'ipc-developers' list to which you are subscribed, but the forum is preferred as it benefits the community in a wider fashion.

    Thankyou very much for taking the time to diagnose the bug.

    Regards,

    - Rob

  • Vesa Peltonen said:

    - when I call  MessageQ_count(g_ddrMsgHandle); it returns -1, which indicates of some error (on DSP side, the count returns zero when there are no messages on the Queue).

    FYI, the MessageQ_count() API is disabled on Linux, for the moment.  It simply returns -1 regardless of the number of messages on the queue.

    Also, the fix we'll be doing is slightly different than simply putting in that single "break;" statement (which I tried to show in my previous post but the formatting got all messed up).  In order to not favor the lowest numbered remote processor, the "next" call to MessageQ_get() should start looking at the next processor cyclically in the ordinal list (i.e., if it found a message on procId 2, it should start the next search at procId 3, with index wraparound until it gets back to the "last" procId for which it found a message).

    Regards,

    - Rob

  • Sounds great! Thanks a lot!

    Cheers, Vesa

  • Hi I am still facing same problem.

    I am using 

    Linux 3.10.72-gca334de on Keystone II

    IPC 3_36_02_13