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.

AM5728: DSP HWI latency jitter

Part Number: AM5728
Other Parts Discussed in Thread: SYSBIOS

I created a SYSBIOS based application that is loosely based on IPC example ex02message.

I overrode the timer tick SWI and added a call to trigger and task when the system timer fires. See

void myTimerTick(void)
{
    Semaphore_post(SEM_TickTask);
    Clock_tick();
}
Void FTSK_TestTask(UArg arg0, UArg arg1)
{
    uint32_t delta;
 
    timing_info.average = 0;
    timing_info.n = 0;
    timing_info.max = 0;
    timing_info.min = 0xffffffff;
    period = Timer_getPeriod(TMR_system);
    while (1) {
        Semaphore_pend(SEM_TickTask, BIOS_WAIT_FOREVER);
        count = Timer_getCount(TMR_system);
 
        delta = count;
        if (delta > timing_info.max)
            timing_info.max = delta;
        if (delta < timing_info.min)
            timing_info.min = delta;
        timing_info.sum += delta;
        timing_info.n++;
        timing_info.average = timing_info.sum / timing_info.n;
    }
}

Then, inside the .cfg file I have

/* Create Timer module */
Program.global.TMR_system = Timer.create(Clock.timerId, '&myTimerTick', timerParams);

The code seems to run fine, but I'm puzzled as to why I get a 34 microsecond maximum latency when the average is 2.66 microseconds....

DSP stats [152373] max 34.81 usec, min 2.06 usec, average 2.66 usec

Note the counter time counts are scaled by

Timer_getFreq(TMR_system, &freq);

if (0 == freq.lo)
freq.lo = 1;

scale = 1000000.0 / (float)freq.lo;

then

sprintf(msg->data, "[%d] max %8.2f usec min %8.2f usec average %8.2f usec\n",
timing_info.n,
(float)timing_info.max * scale,
(float)timing_info.min * scale,
(float)timing_info.average * scale);

With results send back over IPC.

Config.bld contains

Build.platformTable["ti.platforms.evmDRA7XX:dsp1"] = {
    externalMemoryMap: [
        [ "EXT_CODE", evmDRA7XX_ExtMemMapDsp.EXT_CODE ],
        [ "EXT_DATA", evmDRA7XX_ExtMemMapDsp.EXT_DATA ],
        [ "EXT_HEAP", evmDRA7XX_ExtMemMapDsp.EXT_HEAP ],
        [ "TRACE_BUF", evmDRA7XX_ExtMemMapDsp.TRACE_BUF ],
        [ "EXC_DATA", evmDRA7XX_ExtMemMapDsp.EXC_DATA ],
        [ "PM_DATA", evmDRA7XX_ExtMemMapDsp.PM_DATA ],
    ],
    codeMemory: "EXT_CODE",
    dataMemory: "EXT_DATA",
    stackMemory: "EXT_DATA",
    l1DMode: "32k",
    l1PMode: "32k",
    l2Mode: "128k"
};
so as to enable all caches....
What is going on?

 
  • Hi Andrew,

    Are you executing this code on a TI EVM/IDK?

    What version of PRSDK are you using?

    How is the timer configured? What is the expected timer count when an interrupt occurs?

    Have you latched the count data you're using for calculating your statistics into memory so if there are any unexpected count outputs?

    Have you tried toggling a GPIO in the Timer ISR or after the semaphore pend and checking the GPIO on a scope or logic analyzer? This would provide external verification of the timing anomaly you observe in your statistic.

    Regards,
    Frank 

  • Hi Andrew,

    Have you resolved this issue? I plan to close this thread since I haven't heard back from you.

    Regards,
    Frank

  • Hi Frank,

    No, this is not resolved. I have not gotten back to work on it. Are there reference benchmarks that TI generates that measure DSP task response jitter under various loads?

    Thanks,

    Andrew

  • Hi Andrew,

    SYS/BIOS timing benchmarks for various platforms are available in bios_6_76_02_02/packages/ti/sysbios/benchmarks/doc-files/benchmarks.html.
    The benchmarks are described in detail in bios_6_76_02_02\docs\Bios_User_Guide.pdf, Appendix B.

    Except for the "Interrupt Latency" benchmark, these benchmarks can be run using the benchloop example code provided in:
    bios_6_76_02_02\packages\ti\sysbios\examples\generic\benchloop

    This example code outputs min/max/average cycle counts for each executed benchmark.

    Regards,
    Frank

  • Andrew,

    I recommend that you try using the --interrupt_threshold option when building your code.  For example, try using --interrupt_threshold=300 for starters and see if your worst case latency improves (also check the average).

    Most likely the root cause relates to interrupts being disabled for periods of time.  This happens routinely within software pipelined loops so it is important to set a threshold as to how long the compiler is allowed to disable interrupts.  Note that adding this option will only apply to functions you are building, i.e. problematic functions from the RTS library can still cause issues as they are prebuilt without this option.  It looks like you're using sprintf in your code, and that's a problematic function to use.  It would be much better to use LOG_printf.

    Best regards,
    Brad 

  • Thanks Frank. I had a look at the numbers here ti/bios_6_76_02_02/packages/ti/sysbios/benchmarks/doc-files/GCC_A15F_ti_platforms_evmDRA7XX_time.html 

    I think those numbers don't take in to account effects of interfering operations... I'm more interested in worst case results. ie when syslink is processing a message, what is the worst case interference with higher priority task that is being signalled.

  • Andrew Elder said:
    I think those numbers don't take in to account effects of interfering operations... I'm more interested in worst case results. ie when syslink is processing a message, what is the worst case interference with higher priority task that is being signalled.

    The only thing that can hold off interrupt processing is having interrupts disabled.  See my previous post.  I've seen the --interrupt_threshold option resolve many customer's interrupt latency issues.

  • Why is sprintf() problematic? Does it disable interrupts for some reason?

    - Andrew

  • Using --interrupt_threshold will cause the C libraries and SYSBIOS libraries to be rebuilt?

  • Yes, there's an implicit malloc under the hood of sprintf() that disables interrupts.  Worse, since malloc is non-deterministic the amount of time interrupts are disabled tends to get longer as the heap fragments.

  • Andrew Elder said:

    Using --interrupt_threshold will cause the C libraries and SYSBIOS libraries to be rebuilt?

    Not the C libraries.  Just sysbios.