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.

DSP/BIOS Link

The DSP/BIOS Link User Guide (Version 1.63) section 11 Scalability, specifies that the MSGQ component's dependencies include PROC, POOL, MPCS, and MPLIST components.  I was expecting PROC and POOL to be dependencies, however it is not obvious to me how MSGQ depends on MPCS and MPLIST, can somebody explain?  Would I break the MSGQ functionality by removing the MPCS and MPLIST from the build.  I wish to compile the MSGQ components with the bare minimum dependencies.  

Just trying to get some feedback before I spend time experimenting.   

  • I'm not on the dsplink team, but since it's been a couple days I'll throw in my two cents...

    Since MSGQ (message queue) maintains a queue (doubly linked list) of messages, it will inherently have a writer (perhaps multiple writers) and a single reader.  In order for the queue to be in a consistent state you would need a critical section (MPCS).  For example, you wouldn't want the ARM to have updated one of the 2 pointers of the doubly-linked list at the moment the DSP is trying to dequeue an element, i.e. the queue would be in an inconsistent state.  MPLIST is what does the queueing and it builds on MPCS.  So I think overall MSGQ uses MPLIST for the queueing which uses MPCS for atomic accesses.

  • Thanks for previous response. 

    Is it possible to send multiple consecutive messages using MSGQ from the DSP to the GPP?  From the "message" example  included with the DSP Link package, the DSP waits to receive a message from the GPP before it sends another message to the DSP (MSGQ_put, MSGQ_get, MSGQ_put) .  I tried sending two consecutive messages (MSGQ_put, MSGQ_put) but fails when I run it.  My intention is to use MSGQ to send a series of messages to the GPP without having to send a response back after every message.    

     

  • Hi Joe,

    You would need to adjust the software so the DSP does not wait for the answer anymore, etc...

    One thing to pay attention is to make sure whenever you allocate a message, you free it. So for example, in the DSp side you can allocate the message (MSGQ_alloc) and send it, and in the GPP side you can read it and free it (MSGQ_Free).

  • As you suggesed, I adjusted the code so that the DSP does not wait for GPP responses (GPP no longer sends messages back either).  From the DSP side, I'm allocating a message (MSGQ_alloc) once and sending a series of these messages to the GPP without having to wait for GPP responses.  I am also freeing every message after I read it from the GPP side.  However, this only works if there is some wait period in between DSP messages transmissions (MSGQ_put, process...,MSGQ_put).  When I try sending two consecutive transmissions one after the other (MSGQ_put, MSGQ_put),  my app fails at runtime.  Is this expected?  Seems like the DSP messages are not being queued.  I would expect the DSP messages would get queued up for the GPP to read as it can.  Is there's a way to do this?

     

          

     

  • You need to allocate a new message.  Once you send a message you're not allowed to touch it.  The receiver owns it at that point and the receiver has the option to re-use or free the message.  So in your loop you should always alloc and put (not just put).  The receiver should get and free.

  • I am now doing 'alloc' before 'put' every time when sending a message from the DSP (see my DSP side code below) and 'get' followd by 'free' on the GPP side.  With this, I only receive the first message, seems to hang when doing the second alloc on the DSP.  Should I give the second message a unique id?  Any advice?

    for(i=0;i<2;i++){

        /* Allocate and send the message */
        status = MSGQ_alloc (SAMPLE_POOL_ID, &msg, APP_BUFFER_SIZE) ;

        if (status == SYS_OK) {
            MSGQ_setMsgId (msg, info->sequenceNumber) ;
            MSGQ_setSrcQueue (msg, info->localMsgq) ;

            status = MSGQ_put (info->locatedMsgq, msg) ;
            if (status != SYS_OK) {
                /* Must free the message */
                MSGQ_free (msg) ;
                SET_FAILURE_REASON (status) ;
            }
        }
        else {
            SET_FAILURE_REASON (status) ;
        }
    }

     

  • It hangs?  Hmmm, that sounds odd.  MSGQ_alloc() is a non-blocking call so it shouldn't pend or anything.  It should return right away, e.g. SYS_OK or SYS_EALLOC.  It's not returning?  If you halt the processor where is PC?  If you look in the Kernel Object Viewer do you see any stack overflows or anything else that's suspicious?

  • Joe,

    By default, SET_FAILURE_REASON hangs. So your MSGQ_alloc probably failed and then you got stuck in SET_FAILURE_REASON. You should probably confirm by attaching a JTAG and verifying where you are when it hangs.

    Do you have enough buffers configured for your POOL to allow allocating these extra messages? If the writer is fast enough, it can consume all available buffers before reader has a chance to get & free.

    Regards,

    Mugdha

  • I reduced my message size from ~1kb to 128bytes and now I get 8 messages across instead of just 1, seems like I am running out of pool buffers, like you mentioned.  Where do I configure the pool buffers?  I'd like to increase the number of buffers (or total pool size) so that I can queue multiple large ~1kb messages. 

     

     

     

  • Hi Joe,

    Never tried that, but I would try changing the values:

    APP_BUFFER_SIZE

    and

    NUM_MSG_IN_POOL0

    Make sure you change the defines in both sides (DSP and ARM)

  • Thanks, I increased the NUMMSGINPOOL0(20) and APP_BUFFER_SIZE(1kb) and now I am able to send 20 consecutive 1kb messages from the DSP.  I'm still curious on how long it takes the ARM to read and free the message, it seems to be awful slow compared to the DSP (thats expected, I guess).         

    Is it possible to open multiple message queue's with different names?  The intent is to setup two different queues so that these are serviced (read) differently, perhaps give one higher priority over the other.   If so, can somebody advice on how to do this?

    Also, in this same DSP Link message example,  I noticed a queue being set up (MSGQ_setErrorHandler) for async errors.  What is an async error or when would this be needed?  Trying to assess whether I need this for my application.    

     

  • Joe,

    You can create any number of Message Queues that you want (restricted to the max - default is 16 as configured in dsplink/config/all/CFG_ARM.c). There is no prioritization between the Message Queues. You simply need to add one more call to MSGQ_open with a different name to create the new queue.

    Async errors are used to indicate any errors occuring within the transport, which happen asynchronously (i.e. not as part of an API call initiated by the user). For such errors, the user cannot get information about success/failure through a return status value from an API call. Hence the special mechanism of a Message Queue is used to receive messages of the special type (async error type), which would indicate what had gone wrong. However, even though MSGQ module supports using this queue to receive the special async errors, currently our transport does not send any such async errors, so you would never get any of these on your error handler queue. Hence you can safely ignore the async errors or error handler for your application.

    Regards,
    Mugdha

  • I'm experimenting in trying to create two message queues.  I tried doing something that seemed logical to me, however, I'm having issues while trying to locate the second message queue.  Can somebody please review my procedure below and provide feedback?   

    -I declared a second set of variables for my second queue setup (i.e. SampleGppMsgq2, syncLocateAttrs2) to avoid overwriting the first queue's data. 

    GPP-Side

    • PROC_setup
    • PROC_attach
    • POOL_open    //Do I need to open a second pool for each queue (or is that optional)?
    • MSGQ_open   //GPPMSGQ1
    • MSGQ_open   //GPPMSGQ2
    • PROC_load
    • PROC_start    
    • MSGQ_transportOpen     //Do I need to do a transport Open for every queue I open (in this case two)?
    • MSGQ_locate  //DSPMSGQ1
    • MSGQ_locate  //DSPMSGQ2

    -My app hangs while trying to locate the second queue from the DSP

    DSP-Side

    From main, i do two calls to TSKMESSAGE_create for each of my two queues. 

    TSKMESSAGE_create(&info)

    • MEM_calloc
    • SEM_new
    • MSGQ_open   //DSPMSGQ1
    • MSGQ_locate  //GPPMSGQ1

    TSKMESSAGE_create(&info2)

    • MEM_calloc
    • SEM_new
    • MSGQ_open    //DSPMSGQ2
    • MSGQ_locate    //GPPMSGQ2

     

  • Joe,

    Your sequence looks right. To answer your specific questions:

    Q: Do I need to open a second pool for each queue (or is that optional)

    A: No, you don't need to open a second pool. POOL is a system resource, and it has nothing to do with the number of Message Queues you create.

    Q: Do I need to do a transport Open for every queue I open (in this case two)?

    A: No, you should not do transport open multiple times. MSGQ transport is also a system resource. It's used for communicating for MSGQ module between the two cores. Any number of Message Queues can be created. It does not have any impact on number of POOLs or MSGQ transports.

    However, one thing to note is that the number of buffers that need to be configured for ZCPYMQT_CTRLMSG_SIZE should be equal to the number of MSGQ_locate calls that can happen in parallel. In the original sample, it was 2 (NUMMSGINPOOL1) because there were 2 locates happening in parallel (one on ARM and one on DSP). Now that you have increased the number of locates by 2 (one each on ARM and DSP), you should increase NUMMSGINPOOL1 to 4.

    See this: http://wiki.davincidsp.com/index.php/DSPLink_FAQs#What_are_control_messages.3F

    Also, it may be a good idea to look at all DSPLink MSGQ and POOL FAQs here:

    http://wiki.davincidsp.com/index.php/DSPLink_FAQs

    http://wiki.davincidsp.com/index.php/DSPLink_POOL_Module_Overview

    http://wiki.davincidsp.com/index.php/DSPLink_POOL_FAQs

    Regards,

    Mugdha

  • I tried increasing the NUM_MSG_IN_POOL1 from 2 to 4 as suggested but my app still hangs when GPP is trying to locate the second msgq DSPMSGQ2.  Seem like the DSP is failing its MSGQ_open(DSPMSGQ2).  Any other suggestions. 

    Is there a way to run the DSP side standalone on CCS, so I can figure out what is going on in the DSP side?  Its really hard to debug having only visibility to the GPP.

  • Joe Tijerina said:

    Is there a way to run the DSP side standalone on CCS, so I can figure out what is going on in the DSP side?  Its really hard to debug having only visibility to the GPP.

    1)  After the DSPLINK_init() function you can insert a little spin loop:

    volatile int notConnected=1;

    while (notConnected);   // wait for emulator to connect

    2)  Run your program from the command prompt.  The ARM will take the DSP out of reset and do the necessary handshake in DSPLINK_init() and then sit in your spin loop.

    3)  Now that the DSP is out of reset you can connect with CCS (you can't connect if the DSP is being held in reset).  I would not use a gel file because it will mess with the state of things and change the debug environment.

    4)  Do "Load Symbols" (not load program) in CCS so that you can set breakpoints, use watch windows, etc.

    EDIT: 4.5)  Add "notConnected" to a watch window and set it to 0 so that execution continues.

    5)  When you're finished debugging or wish to restart, then you'll need to disconnect from the target.  You should do so before it finishes execution because the DSP will be put back in reset which won't be very smooth for CCS.  (If the target is halted when you disconnect it will resume running automatically.)

    EDIT 5.5) When you reconnect after starting the procedure over again you will need to "refresh" your breakpoints by clearing and resetting them.  There's a "clear all" button and "set all" button under Debug -> Breakpoints.

     

     

     

  • Is it possible that only one message queue can be opened on the DSP side?  Seems that when I try to open a second message queue, the MSGQ_open fails.  On the GPP side, I'm able to open more than one queue with no problem. 

                       ARM                                                                                  DSP

                                                                                              MSGQ_open(DSPMSGQ1)

    MSGQ_open(GPPMSGQ1)                                         MSGQ_locate(GPPMSGQ1)

    MSGQ_open(GPPMSGQ2)                                         MSGQ_locate(GPPMSGQ2)

    MSGQ_locate(DSPMSGQ1)

    This previous setup allows me to have one bi-directional MSGQ (1) and one uni-directional (2), DSP to ARM.

    However, as previously mentioned, if I try adding a second MSGQ_open, it fails the open and causes the DSP to hault. I just want to confirm that this is not possible or whether I should keep hacking at it.

                       ARM                                                                                  DSP

                                                                                              MSGQ_open(DSPMSGQ1)

                                                                                              MSGQ_open(DSPMSGQ2)

    MSGQ_open(GPPMSGQ1)                                         MSGQ_locate(GPPMSGQ1)

    MSGQ_open(GPPMSGQ2)                                         MSGQ_locate(GPPMSGQ2)

    MSGQ_locate(DSPMSGQ1)

     

     

  • Joe,

    This must be because your DSP-side MSGQ config is not correct. This is the default one in our message sample:

    #define NUM_MSG_QUEUES     1

    /** ============================================================================
     *  @name   MSGQ_config
     *
     *  @desc   MSGQ configuration information.
     *          MSGQ_config is a required global variable.
     *  ============================================================================
     */
    MSGQ_Config MSGQ_config =
    {
        msgQueues,
        transports,
        NUM_MSG_QUEUES,
        MAX_PROCESSORS,
        0,
        MSGQ_INVALIDMSGQ,
        POOL_INVALIDID
    } ;

    If your app is derived from this sample, then you'll need to increase the NUM_MSG_QUEUES to the max. number of local Message Queue instances you will have.

    Note that the number of Message Queues will be a local configuration (and not system configuration), because the Message Queue instances are always created locally. Other clients (whether on the same processor or other processors) can get a handle to this Message Queue instance (locating by name), and send messages to it. But the Message Queue itself resides locally and is a local resource (as opposed to some of the other resources such as MPCS, POOL, MSGQ transport etc., which are system resources).

    Regards,
    Mugdha

     

  • Thanks, this solved my issue.

  • Would I be able to share one message queue for two messages (i.e. ControlMsg1 and ControlMsg2) which are of different sizes?   I was successful sending a single message back and forth (ARM->DSP and DSP-ARM) within a message queue but whenever I try sending a different message in that same message queue, my app craahes at runtime.  This is regardless of the direction of the message.  (Note: both of my messages include the MSGQ header). 

    Do I need to open a separate message queue for each different message?

  • Joe,

    You can use messages of any size on a single Message Queue. Since the Message Queue itself is just a local queue that links all of the messages together, the messages on that queue can be of any size, and even allocated from different POOLs if required. The message header in the message has all required information about the message, which can be used by the receiving side to free the message (size, pool ID).

    http://wiki.davincidsp.com/index.php/DSPLink_FAQs#Can_the_Message_Queue_be_used_to_send_variable_sized_messages.3F

    Regards,
    Mugdha