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.

Calling Mcbsp_IOCTL_STOP on Mcbsp driver causes problems

I am using PSP 01_30_01 and Bios 5_41_09_34 on a custom board using the C6746/8. I am using SIO issue/reclaims with call back functions to write data out the mcbsp.

The problem I am having is that in certain error conditions I issue the Mcbsp_IOCTL_STOP on an output stream to the McBsp in order to recover all queued packets sent to the driver so that the system can be "restarted" from a known state. The problem I am having is that the stop command calls Mcbsp_localAbortReset which disables interrupts as it cleans up the floating queue and the pending queue. As it cleans up each packet, it calls the callback function configured for the stream. My call back function reclaims the originally issued buffer and does some minor clean up for the returned buffer. The issue, is that this process seems to take almost 12 mseconds to complete. This is a problem since I have a real time data processing restriction on data that comes in every 2.5 mseconds.

Does the Mcbsp_localAbortReset really need to keep interrupts disabled for its entire clean up process, or only a sub set of it? It seems really dangerous to keep interrupts disabled for an indeterminate amount of time since it just empties out two queues until it is done, but has no idea how large the queues really are.

  • Hi,

    Jeremiah Ferguson said:

    The problem I am having is that in certain error conditions I issue the Mcbsp_IOCTL_STOP on an output stream to the McBsp in order to recover all queued packets sent to the driver so that the system can be "restarted" from a known state. The problem I am having is that the stop command calls Mcbsp_localAbortReset which disables interrupts as it cleans up the floating queue and the pending queue. As it cleans up each packet, it calls the callback function configured for the stream. My call back function reclaims the originally issued buffer and does some minor clean up for the returned buffer. The issue, is that this process seems to take almost 12 mseconds to complete. This is a problem since I have a real time data processing restriction on data that comes in every 2.5 mseconds.

    What is your McBSP settings? How many packets did you prime at the beginning? OR when you call the Mcbsp_IOCTLS_STOP, how many packets are with the driver?

    Jeremiah Ferguson said:

    Does the Mcbsp_localAbortReset really need to keep interrupts disabled for its entire clean up process, or only a sub set of it? It seems really dangerous to keep interrupts disabled for an indeterminate amount of time since it just empties out two queues until it is done, but has no idea how large the queues really are.

    In the "Mcbsp_localAbortReset", we take all the packets in the queue and return it back to the SIO. In the mean time, the EDMA PARAMs will be reconfigured. In this process there are so many shared data strucure being modified/configured. So, it is necessary that we put it in the critical section. 

     

  • Here are my settings for the output channel. Anywhere from 0 to 30 packets could be queued up at a given time. The funny thing is, when I have the 12msec time, there are no packets queued up. Another interesting thing I saw, with no idea how it got into the case, was that somehow as it was emptying the floating queue, it though there were items in the queue, even though none had been added. This led to the callback function being called with a non real packet being reclaimed. After the callback function completed, chanHandle->submitCount was decremented, the problem was, it was already at zero. This of course caused it to go to 4294967296. At this point, everything went weird, my call back function was being continuously called, causing it to eat up 100% cpu until the hardware watchdog kicks in.

    #define NUM_OF_CHANNELS       15   // Max number of Mcbsp channels

    #define BUFALIGN              128   // align buffers to 128 bytes

    #define TX_LOOPJOB_LENGTH 56

     

    #pragma DATA_ALIGN(BUFALIGN);

    uchar TxLoopJobBuffer[TX_LOOPJOB_LENGTH];

    Mcbsp_DataConfig Mcbsp0TXChanConfig =

    {

        Mcbsp_Phase_SINGLE,

        Mcbsp_WordLength_32,

        Mcbsp_WordLength_32,     /* Dont care                */

        NUM_OF_CHANNELS,

        0,                      /* Dont care                */

        Mcbsp_FrmSync_DETECT,

        Mcbsp_DataDelay_1_BIT,

        Mcbsp_Compand_OFF_MSB_FIRST,

        Mcbsp_BitReversal_DISABLE,

        Mcbsp_IntMode_ON_SYNCERR,

        Mcbsp_RxJust_RxJUST_LZF,    /* Dont care for TX         */

        Mcbsp_DxEna_ON

    };

    Mcbsp_ClkSetup Mcbsp0TXClkConfig =

    {

        Mcbsp_FsClkMode_EXTERNAL,

        96000,                   /* 96KHz   ?????                */

        Mcbsp_TxRxClkMode_EXTERNAL,

        Mcbsp_FsPol_ACTIVE_HIGH,

        Mcbsp_ClkPol_RISING_EDGE

    };

    Mcbsp_McrSetup Mcbsp0TXMultiChanCtrl =

    {

        Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED,

        Mcbsp_PartitionMode_CHAN_0_15,

        Mcbsp_PartitionMode_CHAN_16_31,

        Mcbsp_PartitionMode_8

    };

    Mcbsp_ChanParams Mcbsp0TXChanparam =

    {

        Mcbsp_WordLength_32,   /* wordlength configured    */

        &TxLoopJobBuffer,      /* loop job buffer internal */

        TX_LOOPJOB_LENGTH,     /* user loopjob length      */

        reinterpret_cast<Mcbsp_GblErrCallback>(&McbspTXErrorCallback),  /* global error callback    */

        NULL,                 /* edma Handle              */

        1,                    /* EDMA event queue         */

        8,                    /* hwi number               */

        Mcbsp_BufferFormat_MULTISLOT_INTERLEAVED,//Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,//

        TRUE,                 /* FIFO mode enabled        */

        &Mcbsp0TXChanConfig,     /* channel configuration    */

        &Mcbsp0TXClkConfig,      /* clock configuration      */

        &Mcbsp0TXMultiChanCtrl,  /* multi channel control    */

        0x00007FFF, //Channel enable mask for X/RCERE0

        0x00000000, //Channel enable mask for X/RCERE1   40-47

        0x00000000, //Channel enable mask for X/RCERE2

        0x00000000  //Channel enable mask for X/RCERE3

    };

     

     

  • So, you are priming 30 buffers and then reclaiming all the buffer, am i right?

    Can you please try with the 4 buffers and see the same issue been observed?

    Regards,

    Sandeep K

  • This is an outgoing stream, so no priming is needed. Streams are issued as data needs to be sent out. Most of the time there is 0 to 6 buffers that have been issued. Due to the constraints of the overall system, I can not tests with four buffers, doing so would cause other failures to happen.

  • Hi,

    Can you please mention the error which was occuring just before calling the Mcbsp_IOCTL_STOP? Is it going into the error interrupt handler?

    BTW, by looking at the Mcbsp settings, it looks like you are using the Mcbsp in loopjob mode. Have you enabled the loopjob mode in the driver and rebuild the driver?

    Regards,

    Sandeep K

  • It is an application level error that is triggering the need to call Mcbsp_IOCTL_STOP. This is an attempt to get both the PSP driver and application back into a known good state.

    The Msbsp driver has been recompiled with loop job enabled.

  • An additional question. Normally there has to be a balanced number of SIO_issues and SIO_reclaims. Is this still true if you call Mcbsp_IOCTL_STOP? I originally wanted to call SIO_flush or SIO_idle, but the documentation states that since I specified a callback function, these calls do nothing. That is when I found that Mcbsp_IOCTL_STOP aborts all queued up io packets.

    My end goal is to have a method that when something "bad" happens, I can get everything back into a fresh "start up" condition. Whether this is having to reclaim all issued buffers, or finding a way to get the SIO module to forget all previous issues and to start fresh.

  • Hi,

    Actually Mcbsp_IOCTL_STOP or the Mcbsp_IOCTL_CANCEL_PENDING_IO (to cancel the pending buffers) should work for you. But i am not sure why the queues are getting corrupted.

    BTW, there are couple of bug fixes done on the Mcbsp in loopjob mode, which will be released in couple of months.

    In the mean time, you can refer the SYS/BIOS PSP at http://software-dl.ti.com/dsps/dsps_public_sw/psp/BIOSPSP/03_00_01_00/index_FDS.html . The mcbsp driver in this PSP has taken from the 1.30.01 and ported to SYS/BIOS.

    Please compare the drivers and merge the required changes. (Apologies for inconvenience). Do not change anything related to BIOS APIs.

    After the comparision, the changes to be looked for in the driver:

    Mcbsp.c file -> Add a line after 822, Modify line 859 and 864, Add 8 lines after 997, Add 4 lines after 1878, Add 4 lines after line 2112, Update "Mcbsp_localAbortReset()" except the BIOS API's,  

    Let me know the result...

    Regards,

    Sandeep K

  • Thank you for these new source files. Some of these changes we had already made ourselves, so it is nice to see them fixed in an official release.

    I am also making other changes based on the file differences (I am not doing all the differences since some do not affect our configuration)

    Adding 1 line after 3009, 3 lines after 3016, 3 lines after 3091.

    I also had to make changes in mcbsp_edma.c in order to get everything to work. With all of these changes, it seems my problem has been taken care of. Thank you for pointing me to these new fixes.

    Do you know when the official BIOS 5.x version is suppose to be coming out? I think I might also check the Uart and Spi drivers to see if there are any useful fixes in those files.

    Thank you again!

  • Great to know that the fix is working!!

    Jeremiah Ferguson said:

    Do you know when the official BIOS 5.x version is suppose to be coming out? I think I might also check the Uart and Spi drivers to see if there are any useful fixes in those files.

    The DSP/BIOS PSP with the bug fixes might be available in couple of months.

    Regards,

    Sandeep K

  • Sandeep,

    I am having a rare occurance happening that is causing the system stack to overflow. In rare cases when I am trying to rest the McBsp by calling Mcbsp_IOCTL_CANCEL_PENDING_IO, I get in a situation the in the read callback function I call SIO_Reclaim, in stead of returning, it ends up calling the call back function instead (probably caused by dio_reclaim???). I have confirmed this by placing LOG_printf in specific locations and I can see one callback function calling another callback function without ever returning. This eventually leads to the system stack being overrun. Do you have any ideas?

    Jeremiah

  • I suppose, you are using the application callback. And in the application callback you are invoking the SIO_reclaim(). Is my understanding right?

    Regards,

    Sandeep K

  • Ok, in that case, i see a problem. Basically the packet is released when the (application or the BIOS) callback  function is called in the driver. If you invoke the SIO_reclaim() in the callback fucntion itself, then, it is a deadlock, right? Until the callback fucntion is released, the SIO_reclaim() will block and until the SIO_reclaim() comes out, the packet is not released.

    So it is better to have a seperate task context, where you can wait for the semaphore before invoking the SIO_reclaim(). The semaphore can be released in the application callback function.

    Hope this would help you and let me know the result.

    Regards,

    Sandeep K 

     

  • I ended up using SWI_orHook() to do the trick, and it seems to have done the trick, thanks! By the way, is there anywhere in documentation that stated not to call SIO_reclaim directly from the call back function?