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.

Swi Post Latency for C28x

Other Parts Discussed in Thread: SYSBIOS

Hello,

I am seeing a long latency associated with a Swi Post in my code and was hoping that you could help me understand it. 

I'm using:

Experimenter's Kit, Piccolo 320F28069

I have set up a simple SYSBIOS clock.  I want to run it a 16kHz but I can't even toggle a GPIO pin at that speed before my code crashes.  I think the problem is the overhead of running a Swi at that speed.  

My code is very simple.  I set up the SYSBIOS clock to Tick every 100usec.  That post a Hwi upon a Tick.  I call TimerHwi(); which toggles a GPIO pin and posts TimerSwi.  Then TimerSwi calls void tickswi(void).  That's when I toggle the GPIO again.  This results in the following waveform.  I get a nice periodic toggle (100usec), but what I'm looking at is that the time between toggles is 26 usec.  So it takes 26 usec on a 80Mhz device to post a Swi to actually enter it.  That is 2082 cpu cycles.  

I am looking at SPRAAX9 "Using DSP/BIOS in C2800 Applications with High Interrupt Rates," and looking a Table 6 and expecting a latency of something around 500 cycles.  Why am I up to 2000?   I can't live with that much overhead.  How can I reduce it?  I'm not even generating another Hwi here, just measuring the amount of time from the Swipost to when the Swi routine is entered.  What am I doing wrong? 

FYI, I tried to use the SYSBIOS "Timer" instead of the "Clock Module" and got my latency down to 17 usec, so that was good, but still too much for my application (a 16kHz routine is called every 62 usec).  

Note: I am using the settings outlined in the C28x large model Timing Benchmarks: 

file:///C:/ti/bios_6_35_04_50/packages/ti/sysbios/benchmarks/doc-files/C28_large_times.html

Notably:
-Not using any logging 

  1. Library Type (instrumented, non instrumented custom, custom debug): Custom with asserts (-v28 –DLARGEMODEL=1 –ml –m0 -_program_level_compile -03)
  2. Logging disabled
  3. Build profile: release. 
  4. He also mentioned that where you place your code really matters (e.g. RAM vs. Flash), and what are the wait-states on the flash.  I'm not sure how to do that, so whatever the CCS loads into by default is what I'm using.  

Here is my code: 

/*

 *  ======== main.c ========

 */

 

#include <xdc/std.h>

#include <xdc/cfg/global.h>

#include <xdc/runtime/System.h>

//#include <xdc/runtime/Log.h>

//#include <xdc/runtime/Timestamp.h>

#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Task.h>

#include <ti/sysbios/hal/Timer.h>

#include <ti/sysbios/knl/Semaphore.h>

#include <ti/sysbios/knl/Swi.h>

//#include <ti/sdo/utils/List.h> /* List module in IPC */

#include <xdc/cfg/global.h>

#include "DSP28x_Project.h"

void hardware_init(void);

void TimerHwi(void);

void tickswi(void);

 

Uint32 aa = 0;

Uint32 bb = 0;

 

volatile UInt32 t1;            /* temp var for holding first Timestamp */

volatile UInt32 t2;            /* temp var for holding second Timestamp */

Int32 delta;         /* var for output of t2-t1-offset in TIME() */

 

void hardware_init(void)                               //called by main

{

 

// Init PLL, watchdog, periph clocks - see F2806x_SysCtrl.c file

// Clock frequency set to 80 MHz - see F2806x_Examples.h

       InitSysCtrl();

 

// Omitted: Set up GPIO pins

 

*  ======== main ========

 */

void TimerHwi(void)

{

       aa++;

       //Log_info0(“Hwi Posted Now [%u] times”,  aa);

       //Log_info1("The Hwi Clock Ticked [%u] TIMES", aa);

       //t1 = Timestamp_get32();

       GpioDataRegs.GPATOGGLE.bit.GPIO18 = 1;

       Swi_post(TimerSwi);

}

 

void tickswi(void)

{

       //Log_info1("The Swi Clock Ticked [%u] TIMES", bb);

       //t2=Timestamp_get32();

       GpioDataRegs.GPATOGGLE.bit.GPIO18 = 1;

    //delta = t2-t1;

       bb++;

//     Log_info0(“Swi Finished Now [%u] times”, bb);

}

 

Int main()

{

    hardware_init();

    BIOS_start();    /* does not return */

    return(0);

}