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 and IPC problems

Other Parts Discussed in Thread: SYSBIOS, CCSTUDIO

Hello,

Im implementing an ARM-DSP communication using IPC based MessageQ.


When I load and run the DSPs the next message in the /remoteproc0/trace0 appears:

VirtQueue_init(): MultiProc_self already set!

The program nor even start the main from the .c file. It seems to be a configuration file issue, but I had changed many things in the .cfg file but this still appears.

This was just if I want to run the DSPs, therefore when I try it with the ARM side, I think as the DSPs are not initializated well, IPC_start() fails and the application never runs as expected

Does anyone know why is this problem?


Thank you

Ronny

  • Hi Ronny,

    What version of IPC are you using?

    Thanks,

        Janet

  • Janet,

    Im using IPC 3.x

    Any idea of what could be causing this?

    Thank you

    Ronny

  • Hi Ronny,

    We're not really sure why you're getting this error, but suspect it may be caused by a misconfiguration.  Could you tell us what platform you are using and which IPC 3.x version this is?  Also, maybe you can attach your DSP's .cfg file.

    Thanks,

        Janet

  • janet said:

    Hi Ronny,

    We're not really sure why you're getting this error, but suspect it may be caused by a misconfiguration.  Could you tell us what platform you are using and which IPC 3.x version this is?  Also, maybe you can attach your DSP's .cfg file.

    Thanks,

        Janet

    Janet,


    Im using ipc_3_00_04_29, and KeyStone II (TCI6638). The .cfg file is attached.

    Thank you so much for your help

    .1067.MessageQ_Writer.cfg

  • Hi Ronny,

    Can you try changing the order of these lines in the .cfg file:

        var MultiProc         = xdc.useModule('ti.sdo.utils.MultiProc');
        var VirtQueue           = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');

    to

        var VirtQueue           = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');

        var MultiProc         = xdc.useModule('ti.sdo.utils.MultiProc');

    and see if that will cause VirtQueue_init() to be called first?

    Thanks,

        Janet

  • Ronny,

    Yes, I agree with Janet suggestion for change the order of VirtQueue and MultiProc in the cfg file.

    /* IPC */
    var VirtQueue = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');


    /* SDO */
    var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');

    Here, when you call "MultiProc_self" is set during VirtQueue_init based on DNUM.

  • janet said:

    Hi Ronny,

    Can you try changing the order of these lines in the .cfg file:

        var MultiProc         = xdc.useModule('ti.sdo.utils.MultiProc');
        var VirtQueue           = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');

    to

        var VirtQueue           = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');

        var MultiProc         = xdc.useModule('ti.sdo.utils.MultiProc');

    and see if that will cause VirtQueue_init() to be called first?

    Thanks,

        Janet

    Hi Janet and Pubesh,

    I did that, but the problem still appears. See attached image.


    Recall that my XDC modules are:

    var Defaults         = xdc.useModule('xdc.runtime.Defaults');
    var Diags         = xdc.useModule('xdc.runtime.Diags');
    var Error         = xdc.useModule('xdc.runtime.Error');
    var Log         = xdc.useModule('xdc.runtime.Log');
    var LoggerBuf         = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main         = xdc.useModule('xdc.runtime.Main');
    var Memory         = xdc.useModule('xdc.runtime.Memory');
    var Text         = xdc.useModule('xdc.runtime.Text');
    var NameServer          = xdc.useModule('ti.sdo.utils.NameServer');
    var SharedRegion     = xdc.useModule('ti.sdo.ipc.SharedRegion');
    var VirtQueue           = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');
    var Interrupt           = xdc.useModule('ti.ipc.family.tci6638.Interrupt');
    var Resource        = xdc.useModule('ti.ipc.remoteproc.Resource');
    var TransportRpmsg      = xdc.useModule('ti.ipc.transports.TransportRpmsg');
    var VirtioSetup         = xdc.useModule('ti.ipc.transports.TransportRpmsgSetup');
    var NsRemote            = xdc.useModule('ti.ipc.namesrv.NameServerRemoteRpmsg');
    var trans        = xdc.useModule('ti.sdo.ipc.transports.TransportShmCircSetup');
    var System         = xdc.useModule('xdc.runtime.System');
    var SysMin         = xdc.useModule('xdc.runtime.SysMin');
    var Cache           = xdc.useModule('ti.sysbios.family.c66.Cache');
    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');
    var BIOS            = xdc.useModule('ti.sysbios.BIOS');
    var Task            = xdc.useModule('ti.sysbios.knl.Task');
    var MultiProc         = xdc.useModule('ti.sdo.utils.MultiProc');
    var Resource = xdc.useModule('ti.ipc.remoteproc.Resource');
    MessageQ.SetupTransportProxy = xdc.module('ti.sdo.ipc.transports.TransportShmNotifySetup');

    Is anyone of them not necessary?

    Thank you so much for the help

    Ronny

  • Pubesh said:

    Ronny,

    Yes, I agree with Janet suggestion for change the order of VirtQueue and MultiProc in the cfg file.

    /* IPC */
    var VirtQueue = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');


    /* SDO */
    var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');

    Here, when you call "MultiProc_self" is set during VirtQueue_init based on DNUM.

    I was wondering something:

    I few days ago I wanted to try the tests that IPC 3.x brings.  To try them I had to compile the whole IPC-BIOS package with the instruction: make -f ipc-bios.mak        (command 1), in the root directory of IPC 3.x.

    When I did that, of course the executables of each test were generated and I tested specifically the messageq_single.c benchmark. It worked perfectly even with the ARM side.

    As what I am doing is more or less use that code to implement my own communication, I had to create the .cfg file. In the IPC 3.x ../tests/ there are some .cfg, I tried to figure out which was the one used when i wrote the command1 make. I couldnt find it, so I copied sections that I need from some of these configuration files.

    Nevertheless, so far that is not working, since Im having the problem of the VirtQueue_init issue,

    So, maybe you can help me find the right .cfg file to compile against with, in order to re-compile the messageq_single.c benchmark without making the complete IPC.

    Another important thing is that Im using my own make to compile the DSP and ARM images from the shell. Nevertheless I also tried to use the CCStudio to compile the DSP side, with no positive results, the same message when I run the DSP.

    Thank you for your help!

    Ronny

  • Ronny Jimenez said:

    Hi Ronny,

    Can you try changing the order of these lines in the .cfg file:

        var MultiProc         = xdc.useModule('ti.sdo.utils.MultiProc');
        var VirtQueue           = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');

    to

        var VirtQueue           = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');

        var MultiProc         = xdc.useModule('ti.sdo.utils.MultiProc');

    and see if that will cause VirtQueue_init() to be called first?

    Thanks,

        Janet

    Hi Janet and Pubesh,

    I did that, but the problem still appears. See attached image.


    Recall that my XDC modules are:

    var Defaults         = xdc.useModule('xdc.runtime.Defaults');
    var Diags         = xdc.useModule('xdc.runtime.Diags');
    var Error         = xdc.useModule('xdc.runtime.Error');
    var Log         = xdc.useModule('xdc.runtime.Log');
    var LoggerBuf         = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main         = xdc.useModule('xdc.runtime.Main');
    var Memory         = xdc.useModule('xdc.runtime.Memory');
    var Text         = xdc.useModule('xdc.runtime.Text');
    var NameServer          = xdc.useModule('ti.sdo.utils.NameServer');
    var SharedRegion     = xdc.useModule('ti.sdo.ipc.SharedRegion');
    var VirtQueue           = xdc.useModule('ti.ipc.family.tci6638.VirtQueue');
    var Interrupt           = xdc.useModule('ti.ipc.family.tci6638.Interrupt');
    var Resource        = xdc.useModule('ti.ipc.remoteproc.Resource');
    var TransportRpmsg      = xdc.useModule('ti.ipc.transports.TransportRpmsg');
    var VirtioSetup         = xdc.useModule('ti.ipc.transports.TransportRpmsgSetup');
    var NsRemote            = xdc.useModule('ti.ipc.namesrv.NameServerRemoteRpmsg');
    var trans        = xdc.useModule('ti.sdo.ipc.transports.TransportShmCircSetup');
    var System         = xdc.useModule('xdc.runtime.System');
    var SysMin         = xdc.useModule('xdc.runtime.SysMin');
    var Cache           = xdc.useModule('ti.sysbios.family.c66.Cache');
    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');
    var BIOS            = xdc.useModule('ti.sysbios.BIOS');
    var Task            = xdc.useModule('ti.sysbios.knl.Task');
    var MultiProc         = xdc.useModule('ti.sdo.utils.MultiProc');
    var Resource = xdc.useModule('ti.ipc.remoteproc.Resource');
    MessageQ.SetupTransportProxy = xdc.module('ti.sdo.ipc.transports.TransportShmNotifySetup');

    Is anyone of them not necessary?

    Thank you so much for the help

    Ronny

    [/quote]

    Sorry I didnt attached the image properly. Anyway now are attached two images, one within the runtime using my .cfg file , and the other one using the "make -f ipc-bios.mak" generated file called messageq_single.xe66.

    There is a difference as you can see, the one that works has the ouput "virtio_rpmsg_bus virtio: creating channel rpmsg-proto addr 0x3d" while the one generated with my .cfg file doesnt output that line. Why could be the reason for this line to appear or not?

    Thank you for any help!

    Regards,

    Ronny

  • Hi Ronny,

    For the messageq_single, you can use rpmsg_transport.cfg, which includes messageq_common.cfg.xs.  I'm attaching those files, although you should have them in your tests directory.

    7673.rpmsg_transport.cfg.txt

    0385.messageq_common.cfg.xs.txt

    I also asked someone who worked on the IPC 3 product to take a look at your post.

    Best regards,

        Janet

  • janet said:

    Hi Ronny,

    For the messageq_single, you can use rpmsg_transport.cfg, which includes messageq_common.cfg.xs.  I'm attaching those files, although you should have them in your tests directory.

    7673.rpmsg_transport.cfg.txt

    0385.messageq_common.cfg.xs.txt

    I also asked someone who worked on the IPC 3 product to take a look at your post.

    Best regards,

        Janet

    Janet,

    Thank you, it worked nice using both configuration files. I will merge them in order to have only one and I will let you know.

    Regards,

    Ronny

  • Hi there,


    I managed to solve the issues regarding the configuration. Now I have only one .cfg file and errors about the IPC initialization are gone. Now Im facing another trouble that I tried to solved with not good results.

    During the runtime, when I execute my program, I try to send a message using:

    MessageQ_put(queueId,(MessageQ_Msg)msgStruct);

    where msgStruct:

    typedef struct MyMsg {
    	MessageQ_MsgHeader header;
    	char *name;
    	int size;
    
    } MyMsg;
    
    MyMsg *msgStruct;

    When I do the put, the next error appears in the ARM side:

    *** glibc detected *** ./MessageQ_WReader.bin: free(): invalid next size (fast): 0x00011328 ***

    The allocation of the message I do it with:

    msgStruct = (MyMsg *)MessageQ_alloc(HEAPID, sizeof(msgStruct) + payloadSize);

    Any idea of why this happens? The same code used only in DSPs works fine.


    Thank you so much for any help on this!

    Regards,

    Ronny

  • Hi Ronny,

    I'm glad to hear your configuration issues are solved.  I'm not sure what 'payloadSize' in your code is, but maybe that is incorrect.  You could try passing sizeof(MyMsg) to MessageQ_alloc().  Also, the 'name' may be a problem.  Is this pointing to a buffer in shared memory?  You could try starting with an array for 'name' and see if that works.

    Best regards,

        Janet

  • janet said:

    Hi Ronny,

    I'm glad to hear your configuration issues are solved.  I'm not sure what 'payloadSize' in your code is, but maybe that is incorrect.  You could try passing sizeof(MyMsg) to MessageQ_alloc().  Also, the 'name' may be a problem.  Is this pointing to a buffer in shared memory?  You could try starting with an array for 'name' and see if that works.

    Best regards,

        Janet

    Janet,

    Thank you, your help has been very useful for me. I managed to solve the issues of the memory allocation using your advices.

    I have a couple of questions regarding this, sorry Im a newbie.

    How can I know if my program is using Shared Memory? As far as I know you have to put the next lines in the .cfg file:

    var SHAREDMEM           = 0x0C000000;
    var SHAREDMEMSIZE       = 0x00200000;
    
    var SharedRegion = xdc.useModule("ti.sdo.ipc.SharedRegion");
    SharedRegion.setEntryMeta(0,
        { base: SHAREDMEM, 
          len:  SHAREDMEMSIZE,
          ownerProcId: 0,
          isValid: true,
          name: "DDR3_DSP",
        });

    But how Can I assign a given "heap" to reside in the Shared Memory? Should I use the module ListMP of IPC?

    The transports module "ti.sdo.ipc.transports.TransportShmSetup" uses shared memory as default? If not How can I configure my MessageQ application between ARM and DSP to use Shared Memory?


    Thank you so much for your help, Im a bit confused about this.

    Regards,

    Ronny

  • Hi Ronny,

    I talked to one of the Ipc 3.x developers about this, and here is what we think could be happening in your case.  On the Linux side, you call MessageQ_alloc() and MessageQ_put().  The call to MessageQ_put() will copy your message and free it.  Now if you call MessageQ_put() again, without having called MessageQ_alloc(), the same message will be freed again, causing this type of error.  If you don't want the message to be freed up, then you can call:

        MessageQ_staticMsgInit()

    passing your message as a parameter.  Then you are responsible for freeing up the message.  The ping example uses MessageQ_staticMsgInit().  Can you determine where in your code this error is occurring?

    Best regards,

        Janet

  • janet said:

    Hi Ronny,

    I talked to one of the Ipc 3.x developers about this, and here is what we think could be happening in your case.  On the Linux side, you call MessageQ_alloc() and MessageQ_put().  The call to MessageQ_put() will copy your message and free it.  Now if you call MessageQ_put() again, without having called MessageQ_alloc(), the same message will be freed again, causing this type of error.  If you don't want the message to be freed up, then you can call:

        MessageQ_staticMsgInit()

    passing your message as a parameter.  Then you are responsible for freeing up the message.  The ping example uses MessageQ_staticMsgInit().  Can you determine where in your code this error is occurring?

    Best regards,

        Janet

    Dear Janet,

    Thank you for your valued help.

    I will sneak deeper in my code to determine where was this error ocurring. By now, with just following your advices I managed to solve the issues. 

    By the other hand, Did you saw my previous post? Regarding the shared memory.

    If you could help me a bit with that I would really appreciate it.

    Thank you so much!

    Regards,

    Ronny

  • Hi Ronny,

    Yes, TransportShm uses shared memory, and this is the transport used by MessageQ.  So if you use the .cfg files posted earlier, you should be ok.

    Best regards,

        Janet

  • Janet,

    Thank you for your reply.

    I am somehow confused about the behavior of this. If I use MessageQ configured with the next line in the .cfg file:

    MessageQ.SetupTransportProxy = xdc.module("ti.sdo.ipc.transports.TransportShmSetup");
    

    it uses the shared memory as transport means, but how is the message itself put in the shared memory If I am only calling the function MessageQ_put and this only has the remote queue Id and the message as parameters? The MessageQ_put does it automatically?

    Also Im trying to understand if the RPMsg module uses the shared memory. ?

    All of this because, as MessageQ doesnt support big size messages, I need to use the shared memory in order to accomplish this. So at the end, all is resumed in how to pass from ARM to DSP and viceversa big messages using the MessageQ module and the shared memory... ?

    Thanks

    Ronny

  • Hi Ronnie,

    To pass a pointer to a large buffer to the DSP, you need to allocate the buffer using CMEM.  Then use CMEM_getPhys() to get the physical address of the buffer to put into your message.

    I would recommend starting a new forum thread with your questions on RPMsg, as I am not familiar with that.  I am not sure how closely this thread is being monitored, as it has been marked as having a suggested answer.

    Best regards,

        Janet

  • <deleted post made to wrong thread>

  • Hi again,
    My follow-up question above was actually supposed to go into the thread
    e2e.ti.com/.../1199867
    which is the start of this one - it seems to have been forked somehow?
    If someone at ti could move my previous post from earlier today to that thread and delete this post things may eventually seem less confusing ;-)
    Regards /Anders
  • Hi,

    I have now - 1 year after last post above - similar problems with getting IPC to work, described in
    e2e.ti.com/.../425233
    I am interested in whether Ronny got this working and the opinions of Janet's IPC3 colleagues.

    Regards
    /Anders