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.

RTOS/CC2650: Timer with zero latency Hwi

Part Number: CC2650
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

Hi,

Can someone share how to configure a timer to fire at 1kHz with  zero latency ?

This is what I tried without success. The ROV give me an exception.


#include <ti/sysbios/family/arm/lm4/Timer.h> #include <ti/sysbios/hal/Hwi.h>

    Error_Block erroB;
    Error_init(&erroB);

    Timer_Params timer0Params;
    Hwi_Params hwi0Params;

    Hwi_Params_init(&hwi0Params);
    Timer_Params_init(&timer0Params);                           
    timer0Params.periodType=Timer_PeriodType_COUNTS; 
    timer0Params.runMode=Timer_RunMode_CONTINUOUS; 
    timer0Params.startMode=Timer_StartMode_AUTO; 

    uint32_t nominalPeriod=0;
    nominalPeriod=480000/10;    // 1khz
    timer0Params.period=nominalPeriod;
    //hwi0Params.__fxns=foo;
    //hwi0Params.eventId=64;
    hwi0Params.priority=0;
    //hwi0Params.enableInt=TRUE;
    //hwi0Params.useDispatcher=FALSE;
    timer0Params.hwiParams=&hwi0Params;

    timer0Hdl = Timer_create(Timer_ANY, timer0Hwi, &timer0Params, &erroB);

Thanks in advance

PL

  • PL,

    I think the problem is that the type of Hwi_Params you're assigning to the timer0Params.hwiParams element is incorrect. The lm4 Timer module expects that Hwi_Params to be from the ti.sysbios.family.arm.m3.Hwi. module rather than ti.sysbios.hal.Hwi module.

    Try including <ti/sysbios/family/arm/m3/Hwi.h> rather than <ti/sysbios/hal/Hwi.h>.

    Additionally, it is easier to configure a 1ms period using the Timer.PeriodType of Timer_PeriodType_MICROSECS:

        timer0Params.periodType = Timer_PeriodType_MICROSECS;

        timer0Params.period = 1000;   /* 1000us = 1ms = 1KHz */

    Remember that zero latency interrupt functions can not call any BIOS APIs because they do not honor any of the critical section protection throughout the BIOS code. They are essentially non-maskable interrupts.

    Alan

  • Hi Alan

    I modified the code according to your indication and unfortunately the same error appears.
    One strange thing, I observed in ROV that the fxn associated to the Hwi (which is marked as Zero Latency) is "ti_sysbios_family_arm_lm4_Timer_isrStub__E" rather than beeing "timer0Hwi" as I would expect, while the fxn associated to the timer is "timer0Hwi".
    Is this right?

    regards
    PL
  • Please share your new code so I can confirm that it looks correct.

    The lm4 Timer module installs a stub ISR function that acknowledges the timer interrupt prior to calling the user's timer function. As you saw, the Timer ROV view shows your Timer ISR function.

    Is the  problem that the interrupt is not occurring at all, not occurring at the correct rate, or that you're getting an ROV view exception?

    Alan

  • Hi Alan,

    The problem, as in the first post, is that the ROV give me Hwi exception and the execution enters in execption handler. The ISR is never called and In ROV i can see the interrupt is pending.

    Below the code

    thank you

    PL

    #include <ti/sysbios/family/arm/lm4/Timer.h>
    #include <ti/sysbios/family/arm/m3/Hwi.h>
    
    ...
    
        Timer_Params timer0Params;
        Hwi_Params hwi0Params;
        Hwi_Params hwiP;
    
        Timer_Params_init(&timer0Params);
        timer0Params.periodType=Timer_PeriodType_COUNTS;
        timer0Params.runMode=Timer_RunMode_CONTINUOUS;
        timer0Params.startMode=Timer_StartMode_AUTO;
    
    
        uint32_t nominalPeriod=0;
        nominalPeriod=480000/10;    // 1khz
        timer0Params.period=nominalPeriod;
    
        Hwi_Params_init(&hwiP);
        hwiP.priority=0;
        //hwiP.enableInt=TRUE;
        //hwiP.useDispatcher=FALSE;
      
        Hwi_Params_init(&hwi0Params);
        timer0Params.hwiParams=&hwiP;
    
        timer0Hdl = Timer_create(Timer_ANY, fooFxn, &timer0Params, NULL);
        

  • 1) In order to use the ti.sysbios.family.arm.lm4.Timer module in your C code, you must have the following line in your .cfg file:

        xdc.useModule('ti.sysbios.family.arm.lm4.Timer');

    without that line, the clocks to the timers will not be enabled and any access to the timer registers will result in a bus error.

    2) Did you confirm that the handle returned from Timer_create() is non-NULL?

    3) The ROV Hwi Exception view provides an exception backtrace that might help pinpoint the problem. The decoded exception and register context is also quite helpful.

    4) I must again caution you that zero latency ISRs can/should not call any BIOS APIs as the interrupt is not maskable and therefore can interrupt critical section code resulting in state data corruption.

  • Hi Alan

    Thank you,

    I think all 4 points are satisfied (maybe there should be a 5° point to include in the .cfg the xdc.useModule('ti.sysbios.family.arm.m3.Hwi'))

    please find attached the task code, .cfg file and pictures of the error.

    regards

    PL

    error.zip

  • In addition to the previous post as for point 2) the error happens when calling Timer_create so the handle value is not given.

    PL
  • The exception report indicates that the CPU was trying to read from the invalid address 0x20038a34 resulting in a bus error.

    The PSR content reveals that the CPU was executing within the ISR context associated with interrupt number 31 (0x1f), which is the GP Timer interrupt. I suspect that something within that interrupt handler is accessing the bogus location of 0x20038a34 however, the 'fooFxn' function in your task.c seems pretty benign if the PIN_setOutputValue() function is truly commented out.

    Can you share the .map file for this application? Are you using a custom linker command file?

    Alan
  • Hmm. After looking at it more carefully, I think the problem is that the plugged Timer ISR function 'ti_sysbios_family_arm_lm4_Timer_isrStub' expects to be called from the Hwi dispatcher with the associated Timer object as an argument. Since the zero latency ISR mechanism bypasses the dispatcher, the isrStub function is arrived at with whatever was in R0 at the time the interrupt occurred as its argument, thus leading to an invalid dereference.

    To work around this 'feature', I recommend that you create the Timer with 'Timer_StartMode_USER', then use Hwi_plug(31, fooFxn1) to override the Timer_isrStub function.

    In your 'fooFxn1', you'll then call Timer_isrStub(timer0Hdl) to service the timer properly, which will subsequently call 'fooFxn';.

    After creating the timer, you'll need to manually start it by calling Timer_start(timer0Hdl);

    Alan

  • Hi Alan,

    That was exactly the issue, thank you!

    Now, I hope you will report this as a bug to fix since this is not a 'fature' in my opinion. When calling Timer_create that function should automatically set up a different stub function and not 'ti_sysbios_family_arm_lm4_Timer_isrStub' when passing hwiP.priority=0!
    Maybe many other customers would benefit from a fix of this non trivial issue.

    best regards
    PL e2e.ti.com/.../625050