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.

Timer Frequency Dependencies

Other Parts Discussed in Thread: SYSBIOS

Hi all,

I'm working on C6678 with TMDSEVM6678LE Evaluation Module.

I'm trying to use a ISR function (by a timer module instance) in order to create an interrupt every 100us and I'm using a CPU clock frequency = 1 GHz. 

To check the effective interrupt period I toggle a GPIO and I view it on an oscilloscope. 

If I use a CPU clock frequency = 1 GHz the effective interrupt time is 100us, but if I want to increase the CPU clock frequency (e.g. from 1 GHz to 1,25GHz), increasing the performance, the time interrupt changes as well (from 100us to 125us) in contradiction to my expectations.

In fact, in my understanding I suppose that the timer frequency is not CPU clock frequency dependent; in other words if I put 100 us in the period field of Timer - Instance Settings in cfg file I expect that the GPIO is toggle every 100us independent of CPU clock frequency but it is not.

Below my C code:

extern Semaphore_Handle semGG;
CSL_GpioHandle GPIO_handle;
Task_Handle task;
Error_Block eb;
Uint8 outData;
Uint8 count;

/*
* ======== taskFxn ========
*/
Void taskFxn(UArg a0, UArg a1)
{

System_printf("enter taskFxn()\n");

GPIO_handle = CSL_GPIO_open(0); // Opens GPIO Instance 0

CSL_GPIO_setPinDirOutput(GPIO_handle, GPIO_5); // set GPIO_5 to be output
CSL_GPIO_setPinDirOutput(GPIO_handle, GPIO_10); // set GPIO_10 to be output

while (1)
{
Semaphore_pend(semGG, BIOS_WAIT_FOREVER);
CSL_GPIO_setOutputData(GPIO_handle, GPIO_10); // set GPIO_10 to 1
for (count = 0; count < 50; ++count)
{
/*insert a counter to simulate a brief delay*/
}
CSL_GPIO_clearOutputData(GPIO_handle, GPIO_10); // clear GPIO_10 to 0
}

System_printf("exit taskFxn()\n");
System_flush(); /* force SysMin output to console */
}

void testTimer(void)
{
CSL_GPIO_setOutputData(GPIO_handle, GPIO_5); //set GPIO_5 to 1
Semaphore_post(semGG);
CSL_GPIO_clearOutputData(GPIO_handle, GPIO_5); //set GPIO_5 to 1
}

/*
* ======== main ========
*/
Int main()
{
Task_Handle task;
Error_Block eb;

System_printf("enter main()\n");

Error_init(&eb);
task = Task_create(taskFxn, NULL, &eb);
if (task == NULL)
{
System_printf("Task_create() failed!\n");
BIOS_exit(0);
}

BIOS_start(); /* does not return */
return (0);
}

Please could anyone help me?

Thanks In advance

Geni

  • It seems to me, its expected behavior as its depend on CPU clock.
    I think, you are using the system timer (CPU ticks), so you are getting the 125us for the newer frequency.
    You didn't share the code completely and how did you register the "testTimer" function ? (in .cfg file ?)

    You can try to create a separate timer where you can mention the time interval.
  • Can you please try this code ?

    use this in source code (*.c)
    Void Clock0ISR(UArg arg)
    {
    (void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
    (void) platform_delay(50000);
    (void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
    (void) platform_delay(50000);
    }

    Use this in *.cfg file.
    Clock.timerId = 10;
    var clock0Params = new Clock.Params();
    clock0Params.instance.name = "clock0";
    clock0Params.period = 1000;
    clock0Params.startFlag = true;
    Program.global.clock0 = Clock.create("&Clock0ISR", 1000, clock0Params);
  • Hello Titusrathinaraj,

    thanks a lot for your quickly answer.

    I tried your code but I've the same identical problem, increasing the CPU clock frequency increases the interrupt time as well.

    Below the C code:

    /* ================================================================ */

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

    #include <xdc/std.h>
    #include <stdio.h>
    #include <stdint.h>

    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>

    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/hal/Timer.h>
    #include <ti/sysbios/hal/Hwi.h>

    //#include <ti/sysbios/timers/timer64/Timer.h>

    #include <ti/board/board.h>

    #include <ti/platform/evmc6678l/platform_lib/include/evmc66x_gpio.h>
    #include <ti/platform/platform.h>

    #include <ti/platforms/evm6678/package/package.defs.h>


    #include "ti/csl/csl_gpioAux.h"

    #include <ti/drv/gpio/GPIO.h>

    #include <ti/drv/gpio/soc/GPIO_v1.h>


    #include <ti/csl/soc.h>
    #include "ti/csl/csl_chip.h"
    #include "ti/csl/csl_chipAux.h"
    #include "ti/csl/src/intc/csl_intc.h"
    #include "ti/csl/csl_gpio.h"
    #include "ti/csl/csl_gpioAux.h"

    //#include <ti/platform/resource_mgr.h>

    extern Semaphore_Handle semGG;
    CSL_GpioHandle GPIO_handle;
    Task_Handle task;
    Error_Block eb;
    Uint8 outData;
    Uint8 count;

    /*
    * ======== taskFxn ========
    */
    Void taskFxn(UArg a0, UArg a1)
    {

    System_printf("enter taskFxn()\n");

    GPIO_handle = CSL_GPIO_open(0); // Opens GPIO Instance 0

    CSL_GPIO_setPinDirOutput(GPIO_handle, GPIO_5); // set GPIO_5 to be output
    CSL_GPIO_setPinDirOutput(GPIO_handle, GPIO_10); // set GPIO_10 to be output

    while (1)
    {
    Semaphore_pend(semGG, BIOS_WAIT_FOREVER);
    CSL_GPIO_setOutputData(GPIO_handle, GPIO_10); // set GPIO_10 to 1
    for (count = 0; count < 100; ++count)
    {
    /*insert a counter to simulate a brief delay*/
    }
    CSL_GPIO_clearOutputData(GPIO_handle, GPIO_10); // clear GPIO_10 to 0
    }

    System_printf("exit taskFxn()\n");
    System_flush(); /* force SysMin output to console */
    }

    void testTimer(void)
    {
    CSL_GPIO_setOutputData(GPIO_handle, GPIO_5); //set GPIO_5 to 1
    Semaphore_post(semGG);
    for (count = 0; count < 100; ++count)
    {
    /*insert a counter to simulate a brief delay*/
    }
    CSL_GPIO_clearOutputData(GPIO_handle, GPIO_5); //set GPIO_5 to 1
    }

    Void Clock0ISR(UArg arg)
    {
    CSL_GPIO_setOutputData(GPIO_handle, GPIO_5); //set GPIO_5 to 1
    Semaphore_post(semGG);
    for (count = 0; count < 100; ++count)
    {
    /*insert a counter to simulate a brief delay*/
    }
    CSL_GPIO_clearOutputData(GPIO_handle, GPIO_5); //set GPIO_5 to 1


    // (void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
    // (void) platform_delay(50000);
    // (void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
    // (void) platform_delay(50000);
    }

    /*
    * ======== main ========
    */
    Int main()
    {
    Task_Handle task;
    Error_Block eb;

    System_printf("enter main()\n");

    Error_init(&eb);
    task = Task_create(taskFxn, NULL, &eb);
    if (task == NULL)
    {
    System_printf("Task_create() failed!\n");
    BIOS_exit(0);
    }

    BIOS_start(); /* does not return */
    return (0);
    }

    /* ================================================================ */

    Below the cfg file:

    /* ================================================================ */

    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory')
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Swi = xdc.useModule('ti.sysbios.knl.Swi');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');

    /*
    * Uncomment this line to globally disable Asserts.
    * All modules inherit the default from the 'Defaults' module. You
    * can override these defaults on a per-module basis using Module.common$.
    * Disabling Asserts will save code space and improve runtime performance.
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
    */

    /*
    * Uncomment this line to keep module names from being loaded on the target.
    * The module name strings are placed in the .const section. Setting this
    * parameter to false will save space in the .const section. Error and
    * Assert messages will contain an "unknown module" prefix instead
    * of the actual module name.
    Defaults.common$.namedModule = false;
    */

    /*
    * Minimize exit handler array in System. The System module includes
    * an array of functions that are registered with System_atexit() to be
    * called by System_exit().
    */
    System.maxAtexitHandlers = 4;

    /*
    * Uncomment this line to disable the Error print function.
    * We lose error information when this is disabled since the errors are
    * not printed. Disabling the raiseHook will save some code space if
    * your app is not using System_printf() since the Error_print() function
    * calls System_printf().
    Error.raiseHook = null;
    */

    /*
    * Uncomment this line to keep Error, Assert, and Log strings from being
    * loaded on the target. These strings are placed in the .const section.
    * Setting this parameter to false will save space in the .const section.
    * Error, Assert and Log message will print raw ids and args instead of
    * a formatted message.
    Text.isLoaded = false;
    */

    /*
    * Uncomment this line to disable the output of characters by SysMin
    * when the program exits. SysMin writes characters to a circular buffer.
    * This buffer can be viewed using the SysMin Output view in ROV.
    SysMin.flushAtExit = false;
    */

    /*
    * The BIOS module will create the default heap for the system.
    * Specify the size of this default heap.
    */
    BIOS.heapSize = 0x1000;

    /*
    * Build a custom SYS/BIOS library from sources.
    */
    BIOS.libType = BIOS.LibType_Custom;

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x2000;

    /* Circular buffer size for System_printf() */
    SysMin.bufSize = 0x200;

    /*
    * Create and install logger for the whole system
    */
    var loggerBufParams = new LoggerBuf.Params();
    loggerBufParams.numEntries = 16;
    var logger0 = LoggerBuf.create(loggerBufParams);
    Defaults.common$.logger = logger0;
    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    System.SupportProxy = SysMin;

    var socType = "c6678";

    //var plat = xdc.loadPackage('ti.platform.evmc6678l.Settings');

    /* Load the Board package and set the board name */
    var Board = xdc.loadPackage('ti.board');
    Board.Settings.boardName = "evmC6678";

    /*use CSL package*/
    var Csl = xdc.useModule('ti.csl.Settings');
    Csl.deviceType = socType;

    /* Load the gpio package */
    var Gpio = xdc.loadPackage('ti.drv.gpio');
    Gpio.Settings.socType = socType;


    Clock.tickPeriod = 1;
    BIOS.cpuFreq.lo = 1250000000;
    var semaphore0Params = new Semaphore.Params();
    semaphore0Params.instance.name = "semGG";
    semaphore0Params.mode = Semaphore.Mode_BINARY;
    Program.global.semGG = Semaphore.create(1, semaphore0Params);

    //var timer0Params = new Timer.Params();
    //timer0Params.instance.name = "timerGG";
    //timer0Params.period = 100;
    //timer0Params.extFreq.lo = 0;
    //Program.global.timerGG = Timer.create(8, "&testTimer", timer0Params);


    Clock.timerId = 10;
    var clock0Params = new Clock.Params();
    clock0Params.instance.name = "clock0";
    clock0Params.period = 1000;
    clock0Params.startFlag = true;
    Program.global.clock0 = Clock.create("&Clock0ISR", 1000, clock0Params);

    /* ================================================================ */

    PS:

    if I try with:

    (void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
    (void) platform_delay(50000);
    (void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
    (void) platform_delay(50000);

    I have the follow problems:


    - gmake: *** [TestTimePerformance.out] Error 1 TestTimePerformance C/C++ Problem
    - gmake: Target 'all' not remade because of errors. TestTimePerformance C/C++ Problem
    - unresolved symbol platform_delay, first referenced in ./main.obj TestTimePerformance C/C++ Problem
    - unresolved symbol platform_led, first referenced in ./main.obj TestTimePerformance C/C++ Problem

    Thanks in advance for you help

    Geni

  • Any news?

    Thanks
  • Geni Butera, here are my thoughts

    You are right in assuming that in order to get a tick that is independent of the CPU clock you need another source of clock on the board and the device must have a separate timer connected to the second clock. I am not sure if we have it.

    Otherwise, the software translates from cycles to ticks. But if it is software, why no change the cycle counts to get an interrupt? You can have a #define on the CPU clock and describe your formula in the comments

    platform_delay function is in the file platform.c that is platform dependent (of course) you can find it in several places in the release, for example in \pdk_c667x_2_0_3\packages\ti\platform\evmc6678l\platform_lib\src or in
    pdk_c667x_2_0_3\packages\ti\board\src\flash\platform_flash

    Ran