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.

Preventing Timer Function From Being Delayed By Other Interrupts

Other Parts Discussed in Thread: OMAP3530, SYSBIOS

I am having trouble preventing other interrupts from affecting the timing of a timer triggered function. I do not seem to be able to come up with a configuration of the Hwi of the other ISRs and the Hwi of the timer triggered function to allow the timer triggered function interrupt to preempt the other ISRs and prevent the other ISRs from preempting my timer triggered function.

I am using SYS/BIOS 6.33.02.31 on the ARM Cortex-8 of an OMAP3530.

I have tried setting the Hwi maskSetting for the Hwi ISRs to Hwi_MaskingOption_NONE and the maskSetting for the Hwi parameter in the Timer parameter for the timer to Hwi_MaskingOption_ALL but my timer function is still getting interrupted and/or delayed until the other ISRs complete. I can see this on a scope as the occasional stretching of a PWM signal (that’s what I’m using the timer for).

I’m basically trying to do everything possible to keep the timing of the timer interrupt function execution as accurate as possible: even at the cost of delaying other interrupts.

So I guess 1st question is: Do Hwi_MaskingOption_NONE and Hwi_MaskingOption_ALL work for SYS/BIOS on an ARM Cortex-8? The SYS/BIOS manual seems to indicate that on some architectures, only Hwi_MaskingOption_SELF works.

2nd question is: How do I get my timer function to preempt the other ISRs and prevent the other ISRs from preempting it?

Thanks for any help.

  • The interrupt mask parameters are not used for the Arm devices.   The Arm interrupt controllers use an interrupt priority to determine which interrupts will preempt other interrupts.   By default, all interrupts are at lowest priority.   On the arm, a bigger number is lower priority, and a small number is high priority.   Interrupts of higher priority can preempt interrupts of lower priority.   Interrupts of equal priority do not preempt each other.  If more than one is pending, the h/w handles in some predetermined order.  The Cortex-A8 manual will give details.

    I don't have a Cortex-A8 board handy but I do have a Stellaris Cortex-M3 board.   The same rules should apply for the Cortex-A8.

    Here's what you should do:

    [1]  Open ROV to determine the interrupt id and priority for the ISR associated with your timer.   See picture below.    You will also see other active interrupts.  The priority is funny on Stellaris.  The low 5 bits are don't cares, so 224 is 0xe0 which is priority 7.   On Stellaris, you'd use 0xc0 (192) for priority 6.  I'm not sure about A8, but I think A8 is 0-64 and 64 is default.  Again, I don't have board so can't check easily.

    [2]  Add the following code to your .c file:

    #include <ti/sysbios/family/arm/a8/intcps/Hwi.h>

    Hwi_setPriority(id, pri);   /* id from above, pri should be a number less than the others */

  • Thanks for confirming that the interrupt mask parameters are not used for the Arm devices.

    As to the interrupt priorities, although I didn’t mention it in my original post, I did experiment with the interrupt priority before (setting to a lower number than everything else and then a higher number than everything else, just in case) with no noticeable effect either way. The SYS/BIOS priority numbers seem to be 0-63 for the ARM and the default for Timer interrupts is 63.

    And I did also try switching to the A8 specific Hwi, but only in the SYS/BIOS cfg file using: var Hwi = xdc.useModule('ti.sysbios.family.arm.a8.intcps.Hwi'); Before I was using: var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');

    And that also had no noticeable effect. Here’s a screen shot of the ROV window after I set the timer interrupt priority to 2.

    My code actually has 5 separate timer functions as can be seen in the ROV window, but the functions are identical and very short while the timing effects are much larger and are definitely coming from 1 or more of the other interrupts.

    I decided to test again, this time using: #include <ti/sysbios/family/arm/a8/intcps/Hwi.h> in the code, as you suggested. This worked fine for my Hwi related code but caused problems with my Timer related code. I use the following code to set the timer(s) including the hardware interrupt priority for my timer function(s):

       Error_Block ErrorBlock;

       Error_init(&ErrorBlock);

       Timer_Params      TimerParameter;

       Timer_Params_init(&TimerParameter);

       Hwi_Params      HwiParameter;

       Hwi_Params_init(&HwiParameter);

       TimerParameter.runMode     = RunMode;

       TimerParameter.startMode   = StartMode;

       TimerParameter.arg         = Argument;

       TimerParameter.hwiParams   = &HwiParameter;

       HwiParameter.priority      = InterruptPriority;

       HwiParameter.enableInt     = InterruptEnable;

       HwiParameter.maskSetting   = InterruptMask;

    However, when I tried to use: #include <ti/sysbios/family/arm/a8/intcps/Hwi.h> instead of the HAL version in my timer code, there is a compilation error for the statement: TimerParameter.hwiParams   = &HwiParameter; because the Timer.h file uses the HAL version of the Hwi structure, not the A8 version. And they are indeed different (I am using the gpTimer version of Timer.h). I also did not find any Timer.h file that used the A8 version of the Hwi parameter structure. So there does not appear to be any way to use the A8 Hwi.h file with the gpTimer Timer.h file to correctly set the Hwi portion of the Timer parameters.

    Any suggestions?

  • Trying to use the intcps.Hwi module with the gptimer.Timer module will NOT work for the reasons you are running into.

    And since your ROV view  indicates that you have already been successful at setting the Timer's Hwi priorities, I see no value in pursuing that effort.

    The real issue is why hasn't the Hwi priority settings fixed your problem?

    If I interpret the ROV view correctly, I think your 5 Timer interrupts are 40-44 and that you've set them all to priority 2.

    Any of these 5 Timer interrupts will pre-empt any other Hwi of LOWER priority being serviced. However, having all the Timer interrupts at the same priority means that they will NOT pre-empt each other, which means that if they all go off at once, they will be serviced sequentially  from highest to lowest interrupt number (ie interrupt 40 will be serviced last).

    Not knowing your application, I have to challenge your statement that the timer ISRs "are identical and very short". Can  the sequential servicing of the Timer interrupts be causing the jitter you're experiencing?

    Alan

  • As to using the intcps.Hwi and setting the Hwi priorities, thanks for confirming that I can stick with the hal.Hwi and gpTimer versions.

    As to "I have to challenge your statement that the timer ISRs "are identical and very short"." Fair enough. Rather than try to back up my claim, I built a test version of my code that got rid of the other timers that had hwi called functions. Here's the new ROV window:

     

    As you can see, there is only one timer Hwi now with priority = 2. And my timer function is still being affected by the other interrupts.

    Given what I know about my timer function and the other ISRs, the probability is much higher that any given execution delay in my timer function is due to the execution of one or more of the other ISRs "holding off" my timer function than one of the ISRs preempting my timer function (although either would affect the timing and both could be happening). Is there something else I need to configure to be sure my timer function can preempt the other ISRs? Or is there some sort of issue with the A8 version of Hwi? I doubt the later since everything else in SYS/BIOS has been working fine for me on the OMAP ARM, but I can't figure out why the other ISRs keep affecting my timer function.

  • Does your application disable interrupts for long lengths of time? Usage of Hwi_disable()/Hwi_restore() to protect critical section code will effect interrupt latency.

    Also, hopefully you don't have this statement in your config file:

       Hwi.dispatcherAutoNestingSupport = false;

    as this will result in the interrupt dispatcher NOT re-enabling interrupts when it calls the user's Hwi function.

    Alan

  • No calls to Hwi_disable() at all anywhere in my code. Did a file search just to double check.

    Checked my config file and   Hwi.dispatcherAutoNestingSupport = false; is not there. On a lark, added   Hwi.dispatcherAutoNestingSupport = true; to the config file and re-built. No difference. Didn't really expect any, but it was an easy test to try.

  • Your last question about calls to Hwi_disable() got me thinking. Although I don't directly call Hwi_disable(), I do have some gates being used in various places. Not in the H/W ISRs themselves, but in a few Swi functions and in some tasks. I might be using the wrong type of gate for some of these and that could be holding off my timer interrupt function execution. I'm going to look into it and I'll post back.

  • The gates turned out to be my problem. Both using a GateAll in some places I should have been using a GateSwi plus protecting access to some code (SPI bus transfers) that I should not have been. After fixing these areas and redesigning some others, I now have my timer functions with timing jitter less than 0.5 usec. I don't expect to get any better than that with a software based timing solution. Thanks for helping me sort this out.

  • I'm sure glad you sorted this out. I was afraid we were in for a bit of a tedious debug process.

    Alan