AnsweredAssumed Answered

tickless freertos LPTM

Question asked by David Lion on Jul 12, 2018



I try to use FreeRTOS on S32K144, but I am blocked on a timing problem.

I use the tickless feature with LPTM.

For periodic task without any external interrupt I have no problems.

But, when I have external interrupt I have a problem. The calculation  when something other than the tick interrupt ended the sleep seems to be ok for me. But I have sometimes extra time, so my periodic task drift ...


Do you have any ideas for my problem ? 


Here the source code used :


/* Determine if LPTM interrupt occured */
if(isTimerInterruptFire == TRUE )
isTimerInterruptFire = FALSE;
uint32_t ulCalculatedLoadValue;

/* The tick interrupt is already pending, and the LPTM count
reloaded with ulReloadValue. Reset the
CMR register with whatever remains of this tick
period. */
ulCalculatedLoadValue = ulTimerCountsForOneTick - luw_time_ref;

/* Don't allow a tiny value, or values that have somehow
underflowed because the post sleep hook did something
that took too long. */
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
ulCalculatedLoadValue = ( ulTimerCountsForOneTick );

LPTMR0->CMR = ulCalculatedLoadValue;

/* As the pending tick will be processed as soon as this
function exits, the tick value maintained by the tick is stepped
forward by one less than the time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
/* Something other than the tick interrupt ended the sleep.
How many complete tick periods passed while the processor
was waiting? */
ulCompleteTickPeriods = luw_time_ref / ulTimerCountsForOneTick;

/* The reload value is set to whatever fraction of a single tick
period remains. */
ulCompletedSysTickDecrements = ulTimerCountsForOneTick - (luw_time_ref - ulCompleteTickPeriods*ulTimerCountsForOneTick);
/* The reload value is set to whatever fraction of a single tick
period remains. */
LPTMR0->CMR = ulCompletedSysTickDecrements;


/* Restart LPTM so it runs from CMR register
again, then set CMR register back to its standard
value. */
LPTMR0->CSR |= LPTMR_CSR_TEN(1); // timer enable
vTaskStepTick( ulCompleteTickPeriods );


Thanks a lot !