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.

MBX and SEM within SWIs



Here is the gist of the code I'm having trouble with (on a C6713 dsp)

void LogMsg(Int8 *str)

{

//process the str into mbx_in for the mailbox

 

        if (SEM_pend(SEM_Mbox, 0))

        {

            MBX_post(&MBX_Log, &mbx_in, 0);

            SEM_post(SEM_Mbox);

        }

        else

        {

LOG_printf(&trace,"SEM_Mbox is taken");

}

 

}

I'm calling LogMsg from a SWI to log a message into the mailbox.  Before the SWI is done, I'm calling another SWI (from that one) which is also calling LogMsg.  The second ones causes the "SEM_Mbox is taken" statement and it seems like the SEM_Mbox is already taken (this is the only spot SEM_Mbox is used). Even though I call the SEM_post right after the SEM_pend it seems like it doesn't take affect until after it is done with both SWIs and pretty much back to the idleloop.

Pieces of my code was a project that was orgianlly built from CCS 2.2 with a much older bios.  Now we are using CCS 3.3 with the 5.41.06.21 bios

The reason that if (SEM_pend(SEM_Mbox, 0)) is used in the first place is that there is other logs that happen asynchronicity and there was some trouble (in ccs2.2 days) of part of the data in the mailbox being overwritten by asynch logs that were a higher swi.

Thanks

Bryce

 

 

  • Bryce,

    Calling SEM_pend() from the context of a SWI is a big no-no in DSP/BIOS.  Software interrupts must "run to completion" and cannot only be preempted by a higher priority SWI or HWI thread.  If you want to use a semaphore mechanism, it must be done within the context of a task (TSK).

    Dave

  • You can call SEM_pend from a HWI or SWI as long as the timeout is 0, which Bryce is doing.

    What are the priorities of the two SWIs?

    Todd

  • First SWI is the highest priority one that driven from a PRD.  The 2nd SWI is very low priority that takes quite awhile to finish (30 seconds).

  • Hi Bryce,

    Did this get resolved, or is it still an issue?

    Todd

  • I'm still having the issue, but I haven't been actively trying to fix it right now, because I'm fixing another bug.  But if you had any ideas, I would definitely give them a try!

  • ok. I'll see if I can reproduce it. I'll let you know...

  • I was able to reproduce this. The SEM count is decremented when the SEM_pend occurs. The SEM_post does not adjust the count until after any pending SWIs are ran (and there are no TSKs pending on the SEM...in this case the TSK is simply scheduled to be ran).  Here's the simplified test case.

    mySwiFxn()
    {
        // SEM->count = 1
        if (SEM_pend(&SEM0, 0)) {
            // SEM->count = 0
            SEM_post(&SEM0); 
            // SEM->count = 0...until SWIs have ran.     
        }
    }

    I didn't quite understand the issue you were working around. Note: MBX allows for multiple writers so you don't have to manage it yourself. Let me know and we'll see if we can come up with a better design.

    Todd

     

  • Todd,

    With the MBX... would you have to worry about a SWI coming in and writing part of its stuff to the MBX and another higher priority SWI interrupting and writing more to the MBX? Then dropping out of the higher priority finish writing the message to the MBX?

    Or would each of the SWIs have their own message in the MBX?

     

    From what I have been told there was an issue with this on a much older version of ccs 2.2 or earlier (as well as a earlier bios).  So maybe this was to fix a  legacy issue we don't have to worry about anymore??

     

    Thanks 

    Bryce

     

     

  • Bryce,

    MBX_post is thread-safe. If a higher priority SWI interrupts another SWI in the middle of a MBX_post, one of two things will happen

    1. If there are no free buffers available, the interrupting MBX_post returns FALSE.

    2. If there are free buffers available, the interrupting MBX_post gets a free buffer, fills it in and returns TRUE.

    The two SWI's will never act on the same buffer.

    Who is calling the MBX_pend? A TSK or a SWI? There are some corner cases if use are using a SWI to call MBX_pend. As I noted before, the SEM_post does not increment the count until the SWIs are done running, so if you have a SWI that does MBX_post, the internal SEM's count is not incremented until the SWIs are done. So the following behavior happens (similar to the SEM_pend, SEM_post behavior).

    Void mySwi()
    {
        ...
        rc1 = MBX_post(mbx0, msg1, 0); // assume returns TRUE and the length for the MBX is 1
        rc2 = MBX_pend(mbx0, msg2, 0); // will return FALSE since the internal SEM's count is still 0...
                                      // it will increment after the SWI's complete.

    If you are calling MBX_pend in a TSK, the above MBX_pend would return TRUE and msg2 would have been filled in.

    Todd

  • That makes sense.   I'll give it a try without the sem_pend and I'll double check that all my logs are being written appropriately.

     

    The MBX_pend is being called from a TSK, so I should be OK with that.

     

    Thanks

    Bryce