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.

MSGQ usage: blocking or not blocking?

Other Parts Discussed in Thread: SYSBIOS

Hello people,

as my first post in this excellent community I have the following doubt.

I will use the MSGQ module for inter-cores communication on C6616 DSP. If I use, at the receiving side, the

MSGQ_get()

function, shall I block the receiving task on this call?

Or, shall the receiving task be woken by the operating system as the sender has sent its message, and then the receiver will get it via MSGQ_get() ?

Thanks

Roberto

 

  • Roberto --

    You will need SYS/BIOS 6.31.0x and IPC 1.22.0x for use on the C6616 processor. 

    You can get them at the link below.  Note that full source code is provided with both releases under BSD license.

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/index.html

    IPC 1.22 provides the multicore communications.   The 'MessageQ' module is the follow-on to MSGQ.

    Default behavior is for MessageQ_get() to suspend the running thread on an internal call to Semaphore_pend().  If a message is available, then the thread returns immediately.  If no message is available, then the calling thread blocks on the call to Semaphore_pend() until the remote core sends a message across, which triggers an interrupt on the local core, which queues the message on the correct input queue and calls Semaphore_post() to release the blocked thread.

    It is possible to use MessageQ_get() in a non-blocking way where you poll for messages.  There's a MessageQ_create() parameter to support alternate synchronization schemes. 

    -Karl-

  • Hello Karl,

    thank you for your excellent answer.

    What do you exactly mean for follow-on to MSGQ? Is the MSGQ module only supported for backward compatibility, and I need to use the MessageQ instead?

    Roberto

     

  • Hello again,

    another issue met today (my cores are still not communicating....)

    do I need to set the Transport underneath, or will the ipc_start() do that for me?

    Roberto

  • Hi Roberto,

    What sort of problem are you having?  Do you do a MessageQ_put on core A but core B never returns from MessageQ_get?  Perhaps you are missing some configuration required to configure MessageQ correctly...

    Ipc_start should automatically create transports if you've configured the IPC module to do so with the following configuration in your .cfg file:

       /* Synchronize all processors (this will be done in Ipc_start) */
       Ipc.procSync = Ipc.ProcSync_ALL;

    By default, mechanisms used to communicate between 2 cores (such as MessageQ transports and Notify drivers) are only made available when Ipc_attach is called between the two cores.  However, when you use ProcSync_ALL, Ipc_start also does Ipc_attach between the local processor and every other remote processor.

    A good place to start if you've never used MessageQ with IPC is the C667x MessageQ example that accompanies the IPC product.  You can find this example at [IPC_INSTALL_DIR]\packages\ti\sdo\ipc\examples\multicore\evm667x\message_multicore.[c,cfg].  This is a single image example--you will be able to build once and load the image on all the cores on your device.

    You will also find an install guide that explains how to build the IPC examples at [IPC_INSTALL_DIR]\docs\IPC_Install_Guide.pdf.

    Regards,

    Shreyas

  • Hello Shreyas,

    I have a messageQ_create on the reader core that is successful; neverthless the messageQ_open on the writer core never returns a successful status value; actually it always returns -5 i.e. MessageQ_E_NOTFOUND.

    I have followed the user guide and the example you indicated, but still I have that the writer processor does not find the reader queue. Only difference is that I am using static allocation of te message to be sent by the writer, but I do not think this could be a problem because it would come afterwards...instead, I am stuck at finding of the queue by the writer, it seems that the two cores are not seeing each other.

    I am trying all the possible, but if you have an idea of what it could be it would be great. Imho, I am still missing some module to be loaded...

     

    ROberto

  • Roberto,

    Are the two cores attached to each other?  I.e. has a transport and notify driver been created so the two cores can communicate with each other using MessageQ and/or Notify? If notifications aren't enabled yet, then MessageQ_open (which uses notify under-the-covers) will always return MessageQ_E_NOTFOUND since it won't be able to query the remote processor.

    You can check this in CCSv4 using the ROV tool.  Go to Tool--> ROV to launch ROV.  If you haven't used it before, you might be prompted to set it up (simply make sure that XDCTools, BIOS and IPC are selected in the configuration pane).

    Once ROV is set up, navigate to the view for the ti.sdo.ipc.Ipc module and examine the 'attached' column.  If the value for the remote processor is 'false' then the connection hasn't been established yet.

    If none of this solves your problem, could you post your source files (.c and .cfg) on this thread?

    Regards,

    Shreyas

  • Roberto,

    I fully expect Shreyas has you down the right path, but there is another thing to try...Can you try opening the queue on the same core that it is created. This rules out any typos with the name.

    Todd

  • Hello guys,

    the ROV tool was actually very useful, thanks to it I found the problem, I was not naming correctly the cores in the cfg.

    Now, the cores are communicating. I still get an error when the reader core receives the first message from the writer, but I'd investigate by myself this one.

     

    Thanks to all!!

     

    Btw, the error is the following :)))

     

    ti.sdo.ipc.MessageQ: line 442: assertion failure: A_invalidObj: an invalid obj is used
    ti.sysbios.gates.GateMutex: line 114: assertion failure: A_badContext: bad calling context. See GateMutex API doc for details.
    xdc.runtime.Error.raise: terminating execution

     

    and happens just after the first message has bben received by the reader core.

  • The MessageQ error might be happening because CORE A is trying to send a message to a queue on CORE B that doesn't exist yet.  When you do a MessageQ_put on CORE A, MessageQ first checks whether the message is destined for a remote processor.  If so, it goes through the transport and arrives on the remote side and it is placed on the local queue via MessageQ_put.

    I think it's the 2nd MessageQ_put that is failing for you because the queueId is invalid or the corresponding queue doesn't exist yet.  Did your MessageQ_open succeed?  What is the value of your queue ID that was returned by MessageQ_open and on what processor does your queue reside?  You can again use ROV to diagnose your problem--check the value of queueId being supplied to MessageQ_put against the ids of queues present on the remote processor's MessageQ ROV view to make sure the remote queue exists.

    Shreyas

  • Hello,

    yes the MessageQ open succeeds, but a very strange thing happens if I chekc the situation in the ROV. When I chek the status of the MessageQ in core 1 (the one that receives the first message and then crashes) I get the following:

     

    Received Exception from ROV server:

    java.lang.exception: target emory read failed at address 0x0,lenght: 8

    This read is at an invalid address according to the application section map. The application is likely either uninitializer or corrupt.

     

    I can't figure out whether this problem is related to the ROV or the application itself....

     

    ROberto