Skip to content

Commit

Permalink
xtensa port: count ticks separately
Browse files Browse the repository at this point in the history
If xTaskIncrementTick is called while the scheduler is suspended then OS
tick counter update is delayed. vPortSuppressTicksAndSleep is always
called with suspended scheduler, so timer deadline in ccompare SR may
not correspong to the current OS tick. Count ticks separately in the
port and use that counter to calculate future timer deadlines.

Signed-off-by: Max Filippov <[email protected]>
  • Loading branch information
jcmvbkbc committed Feb 24, 2020
1 parent 5742688 commit 0f0816c
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion portable/XCC/Xtensa/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ extern void _xt_task_start( void );
static uint32_t xt_tick_cycles;
TickType_t xMaxSuppressedTicks;

static uint32_t xt_tick_count;

#if ( configUSE_TICKLESS_IDLE != 0 )
// Flag to indicate tick handling should be skipped.
static volatile uint32_t xt_skip_tick;
Expand All @@ -114,6 +116,7 @@ static void xt_tick_handler( void )
if ( xt_skip_tick )
{
vTaskStepTick( xt_skip_tick );
xt_tick_count += xt_skip_tick;
xt_skip_tick = 0;
}
#endif
Expand All @@ -135,6 +138,7 @@ static void xt_tick_handler( void )
interruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
ret = xTaskIncrementTick();
++xt_tick_count;
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( interruptMask );

Expand Down Expand Up @@ -165,6 +169,7 @@ static void xt_tick_timer_init( void )
xMaxSuppressedTicks = 0xFFFFFFFFU / xt_tick_cycles;
xt_set_interrupt_handler( XT_TIMER_INTNUM, (xt_handler) xt_tick_handler, 0 );
xt_set_ccompare( XT_TIMER_INDEX, xthal_get_ccount() + xt_tick_cycles );
xt_tick_count = xTaskGetTickCount();
xt_interrupt_enable( XT_TIMER_INTNUM );
}

Expand Down Expand Up @@ -329,7 +334,7 @@ void vPortSuppressTicksAndSleep( TickType_t target, TickType_t xExpectedIdleTime
uint32_t skip_tick;
uint32_t now;

xExpectedIdleTime = target - xTaskGetTickCountFromISR ();
xExpectedIdleTime = target - xt_tick_count;
// Compute number of cycles to sleep for, capped by max limit.
// we use one less than the number of ticks because we are already
// partway through the current tick. This is adjusted later below.
Expand Down Expand Up @@ -377,6 +382,7 @@ void vPortSuppressTicksAndSleep( TickType_t target, TickType_t xExpectedIdleTime
do
{
vTaskStepTick( ticks );
xt_tick_count += ticks;
xt_set_ccompare( XT_TIMER_INDEX, ccompare );
diff = xt_get_ccount() - ccompare;
ccompare += xt_tick_cycles;
Expand All @@ -387,6 +393,7 @@ void vPortSuppressTicksAndSleep( TickType_t target, TickType_t xExpectedIdleTime
else
{
vTaskStepTick( skip_tick );
xt_tick_count += skip_tick;
}

xt_skip_tick = 0;
Expand Down

0 comments on commit 0f0816c

Please sign in to comment.