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.

context switch

Other Parts Discussed in Thread: SYSBIOS

Hello

I need a very precise jump into a HWI, and the data seems to say that when the RTOS is in idle loop, the HWI runs about 16uS earlier than when I'm running a task.

Is there a difference in context switch times when you're running a task vs. sitting in the idle loop?

I'm perfectly fine with the extra 16uS, however the delay must be consistent for the system to function properly.

  • Chris,

    Which processor are you using?

    Which version of DSP/BIOS or SYS/BIOS are you using?

    Which compiler version?

    Mark

  • Mark,

    C6748,  SYSBIOS 6.37.00.20,  Compiler 7.4.5

  • Chris,

    There's no differentiation between a non-idle task and the idle task as far as interrupt handling is concerned. Some things to check:

    • are you disabling interrupts in your task code - Hwi_disable()
    • are you using any libraries that might be disabling interrupts?
    • since this is a C674 device, do you have any really long loops where the pipeline could be disabling interrupts? This would have to be a lot since 16 uS is several K's of cycles at 300+ MHz

    The worst case interrupt latency for the SYS/BIOS kernel for the C674 is < 100 cycles, so 16 uS is a lot worse.

    Mark

  • Mark,

    I'm not calling HWI_disable().

    We do have a long loop ( ~60,000  32x32 floating point multiplies).  While running in debug, this takes ~7mS, and using the execution graph I can see that I'm still jumping into the interrupts, although during this task is when the time between the trigger, and the start of the mcbsp transfer seems to take longer.

    I'm using a GIO_issue, to get the data, could that have anything to do with it?  The code below is what I'm using.  I used to have the GIO_issue in the task on the line before the GIO_reclaim, but as an experiment I tried putting it in the ISR.  I'm aware this isn't the best way to do things, (anytime I pause and restart debugging I get an assert error from GIO.c)

    //HWI tied to GPIO line

    void usr_SYNC_ISR(void)

    {

        GPIOPinIntClear(SOC_GPIO_0_REGS, BITSYNC_IN);

        //issue buffer to MCBSP
        GIO_issue(mcbspRxHandle,mcbsp_buff_ptr, mcbsp_rx_len_bytes, NULL);

        Semaphore_post(mcbspEnableSem);
    }

    //in the task

    while(1)
    {
        for(i=0;i<ST_SAMPLE_LEN;i++)
        {
            //wait for semaphore
            Semaphore_pend(mcbspEnableSem, BIOS_WAIT_FOREVER);

            //reclaim buffer from MCBSP
            status = GIO_reclaim(mcbspRxHandle, (Ptr *)&rcv, &mcbsp_actual_rx_bytes, NULL);

            //set the queue record entry value to the (pointer) averaged value
            pQEntry->buffptr = rcv;
            Queue_put(mcbspSampleQ, &(pQEntry->elem));

            //allocate new buffer in iheap 
            mcbsp_buff_ptr = (Ptr)Memory_alloc(iheap,MCBSP_RX_LEN_BYTES,32,&eb);

           pQEntry = (Ptr)Memory_alloc(qheap,Q_ENTRY_LEN,0,&eb);

        }

        //post Semaphore to Algorithm (data available)
        Semaphore_post(avgSem);

    }

  • I should clarify that when I say "latency" I'm referring to the time between the falling edge trigger, and the first FSR pulse on the mcbsp bus.  That time is ~16uS.

    The mcbsp task that I wrote above is the highest priority task.  

    I can try setting an LED or something when I'm in the ISR to get the actual HWI latency.  If that's consistent, then I'm left to conclude that the issue is with the GIO issue/reclaim.

  • Chris,

    Depending on how you compile your code, you could be disabling interrupts for a long time in your math routine. See this wiki article:

    http://processors.wiki.ti.com/index.php/Interrupts_Disabled_by_C6000_Compiler

    Are you using the -mi or --interrupt_threshold option?

    Calling GIO_issue() from an ISR should not be a problem - it's a non-blocking call. Looking at your code snippet, I'm not sure why you have the Semaphore operations? The task code should just block on GIO_reclaim() until the data comes via your starting it with GIO_issue().

    What assert are you getting when you debug? I don't see any relevant asserts in the source for GIO.c.

    Mark

  • Mark,

    I will take a look at the compiler options... but supposedly the pipelining is only enabled under o2 and o3 optimization, and I'm running in debug mode with no optimization. 

    Thanks for the tip on the semaphores.  I'll give that a shot.

    The assert was GIO.c line 508.  It's a few lines in on the GIO_issue() function.  I got this error whenever I paused the debugger, and then resumed operation.  The only way to fix this was to do a system reset from CCS or a POR.  This only happens when the GIO_issue() is called from the ISR.  

  • Mark,

    There's definitely no -mi option in the compile. 

    I added a GPIO toggle at the beginning and end of the ISR code.  That's where the issue is.  The time in the interrupt with the GIO_issue() call is 11uS min to 29uS max.

    Is it possible to initialize mcbsp with BIOSPSP driver (3.00.01.00), then manually set the EDMA3 params, and use the ISR to just set the dst address in EDMA3 and the mcbsp FRST bit, then use edma3 callback function to reset the FRST bit and post the semaphore?  This should be much less overhead than using the GIO_issue/reclaim

    I guess I'm trying to ask if the driver will allow me to do that, or if it blocks access of those registers unless I'm using the TI APIs.

  • Mark,

    I ran this on release mode (hence the difference in timings) but this illustrates the issue.

    This is the envelope plot of the ISR start time (purple trace) compare to the sync line (yellow trace).  You're seeing multiple traces overlapped, so the purple blob is the jitter of when the ISR starts.  The blue traces are the FSR pulses from mcbsp.

    So, that's one issue, the jitter in the ISR staring.  I have this set up in the .cfg file as interrupt number 5, priority 1.

    So then, there's a huge difference of how long the ISR takes.  This ISR is the one I wrote in previous, with the addition of the GPIO line being toggled.  There seems to be a major difference in the GIO_issue() timing, or else it's being preempted by another interrupt during the ISR.

     

  • Chris,

    Fun problem :)

    Looking ahead to when the timing works, you should insure you use -mi with your algorithm code when you turn on optimization, i.e., non-debug build.

    The jitter in the ISR start time does not seem too far off from what might be expected. If I interpret the trace correctly (nice - thanks for providing), the ISR jitter is 350ns (960 - 610). Not sure of your C6748 clock speed, but this would be <150 clock cycles, which could be accounted for by kernel latencies or other disabling of interrupts in the system.

    I'm not really familiar with the McBSP peripheral (other than I know it has lots of different operating modes) nor with the McBSP driver in the PSP you are using, so I have no suggestions for the ~7us jitter in the "issue()" function time. I took a quick look at the source code for the "issue()" method for McBSP - which comes down to the mcbspSubmitReq() function in Mcbsp.c. I don't see anything obvious related to kernel usage. Not sure about the McBSP or EDMA operations, though.

    You may need to find a McBSP and/or EDMA expert for this.

    Mark

  • Mark,

    Thanks.  I ended up nixing the PSP driver.  The mcbsp task does the intialization and sets up the EDMA.

    The HWI isr enables the mcbsp FSR 

    The EDMA handles the buffer filling

    EDMA callback disables the mcbsp FSR, and posts the semaphore to the mcbsp task.

    The results are much more consistent than using the GIO_issue command.  There's still jitter in the ISR trigger, but it's under a uS (when the algorithm is not running).  We still see about a 5uS jitter when the algorithm is enabled.

    I will make sure to use the -mi compile option.

  • Chris,

    Glad you have it working. It's hard to fit every use case into the drivers, so sometimes it's best to treat them as examples and write your own custom "driver".

    Mark

    (Please mark this "solved" if you are satisfied.)