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 Hwi Overhead

Other Parts Discussed in Thread: EK-TM4C1294XL, SYSBIOS

Hi all,

I am having issues getting a timer hwi to run at speeds greater than 80kHz.

The hwi works well for timer speeds up to about 160kHz, but from then on the frequency of the interrupt is capped at about 160kHz.


The code used to setup my timer and hwi, as well as the hwi isr is listed below:

main() {

....

	#define CLK_FREQ			30000000
        uint32_t ui32ClockFreq;

	// Set clock frequency
		ui32ClockFreq = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN |
		SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, CLK_FREQ);

	// Enable timer peripheral clock
		SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
		SysCtlPeripheralReset(SYSCTL_PERIPH_TIMER0);
		while (!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0)) {
		}

	// Configure the timer
		TimerConfigure(TIMER0_BASE, TIMER_CFG_A_PERIODIC_UP);
		TimerLoadSet(TIMER0_BASE, TIMER_A, (ui32ClockFreq / 200000));

	    //
	    // Setup the interrupt for the timer timeouts.
	    //
            hwi = Hwi_create(INT_TIMER0A, hwi0_isr, NULL, NULL);

	    IntEnable(INT_TIMER0A);
	    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

	    TimerEnable(TIMER0_BASE, TIMER_A);

}


void
hwi0_isr(void)
{
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, toggle);
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, !toggle);
}

So really my question is am I doing this right? And if so, is there/why is there such a large overhead when using a hwi. 

Many Thanks,
Andrew.

  • Hi Andrew,

    Which version of TI-RTOS are you using and what device are you running on?

    Best,
    Alexander
  • Hi Alexander,

    Sorry about that, device is EK-TM4C1294XL, and the rtos version is 2.16.00.08.
  • Thanks for the info,

    It looks like the goal of your application is to first change the CPU frequency, configure a periodic timer and subsequently set up a HWI object to service the interrupts. Could you instead simply use the Timer module that BIOS provides? This will take care of creating/configuring your timer in addition to making you're HWI for you.

    This should accomplish what you have above from lines 15-26:

    #include <ti/sysbios/hal/Timer.h>
    
    void
    hwi0_isr(UArg arg)
    {
        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, toggle);
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, !toggle);
    }
    
    /* Set-up Timer */
    Timer_Params prms;
    Timer_Handle timer;
    
    Timer_Params_init(&prms);
    /* Note this expression would yield a period of 600 cycles when ui32ClockFreq is 120MHz */ prms.period = (ui32ClockFreq / 200000); /* Configure timer to count ticks rather than microseconds */ prms.periodType = Timer_PeriodType_COUNTS; timer = Timer_create(Timer_ANY, hwi0_isr, &prms, NULL); In your .cfg file: var Timer = xdc.useModule('ti.sysbios.hal.Timer');

    As for the overhead you're seeing, that's is due to the interrupt latency. In essence, the scheduler must move through a context switch when moving between threads( Ex. Task preempted by your timer Hwi). You can view other benchmarks such as interrupt latency in your TIRTOS BIOS installation.

    EX. C:\ti\tirtos_tivac_2_16_00_03_eng\products\bios_6_45_01_25_eng\packages\ti\sysbios\benchmarks\doc-files

    and looking at the benchmarks.html page.

    In addition to the benchmarks you may also view the API documentation in your installation.

    EX. C:\ti\tirtos_tivac_2_16_00_03_eng\products\bios_6_45_01_25_eng\docs

    and looking at the Bios_APIs.html page.

    Best,

    Alexander

  • Thanks for the reply Alex,


    Only just got the time to test the code out. The BIOS timer looks a lot more consistent and easier to setup, so thanks for that.

    But the issue of the overhead still remains. I know there is no way to get past it when using a hardware interrupt, but are there any other options to try and achieve an interrupt routine that fires at 250kHz and upwards? Or is that just too fast for TI RTOS?

    Cheers,
    Andrew.

  • Hi no problem,

    So for M3 devices, we support "Zero latency" interrupts which would alleviate your problem , but be aware you may not call certain BIOS API's from this ISR.

    From the API documentation:

    As such, you can create the timer like I showed you above, but pass in your zero latency Hwi parameters (Priority of 0).

    /* Replace the hal timer include with the family specific */
    #include <ti/sysbios/family/arm/m3/Timer.h>
    
    Timer_Params prms;
    Hwi_Params *hwiParams;
    .
    .
    .
    
    hwiParams.priority = 0;
    prms.hwiParams = &hwiParams;
    
    
    And update your .cfg file to include the family specific Timer module.
    var Timer = xdc.useModule('ti.sysbios.family.arm.m3.Timer');


    Best,
    Alexander