xTickCount start value

m-wagner wrote on Monday, October 24, 2016:

Hi @all,

I’m doing some time calculations that use the OS tick as base. This requires me to analyze my apps behaviour on tick wrap over. As I don’t want to wait until this happens, I now have to change FreeRTOS code to change xTickCount.

Is there a reason why the tick start value is not set to some value a few seconds/minutes before wrap over, like in Linux kernel (https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/include/linux/jiffies.h?id=a2b42342b2cb55d9b41ce36396334525f99ba17d INITIAL_JIFFIES )?

I know that this will not magically detect all wrap over errors, but it might help detect some :slight_smile:

Thanks,
Martin

rtel wrote on Monday, October 24, 2016:

Sorry I don’t know anything about the implementation of the Linux
kernel. You can set the initial tick value to whatever you want - the
FreeRTOS code as delivered tries not to have any variables initialised
to anything other than 0 so as not to have variables outside the .bss
section.

If you have configUSE_TICKLESS_IDLE set to 1 you could also conceivable
use vTaskStepTick() to push the tick count forward too, but probably the
only safe way of doing that would be to create a single task, have that
task call vTaskStepTick() to step the tick count forward by however many
ticks you want, then create your other application tasks.

m-wagner wrote on Tuesday, October 25, 2016:

Thank you for your answer.
Using vTaskStepTick() works for me.

Starting the tick at some special value is not Linux specific. I just used Linux as an example.

/*
 * Have the 32 bit jiffies value wrap 5 minutes after boot
 * so jiffies wrap bugs show up earlier.
 */
#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))

This is done so that at 1 kHz the tick overflows for the first time after 5 minutes instead of ~50 days. The risk of having a hard-to-find error related to tick wrap over is thereby reduced a bit.

rtel wrote on Tuesday, October 25, 2016:

If it is useful to people I will add something similar to the FreeRTOS code.

davedoors wrote on Tuesday, October 25, 2016:

Set configUSE_16_BIT_TICKS to 0, then the tick will overflow every few seconds.

cmcqueen1975 wrote on Tuesday, November 15, 2016:

I would find it useful. Bugs related to wrapping may lurk in time delta calculations, so it’s good if such wrapping occurs regularly during testing (after a device has been running for a few minutes) rather than once something is running “in the wild” for ~50 days.

#ifndef configTICK_COUNT_INIT
#define configTICK_COUNT_INIT    0u
#endif

Then in vTaskStartScheduler():

xTickCount = ( TickType_t ) configTICK_COUNT_INIT;

I’ve just been looking through the FreeRTOS 9.0.0 code to see if it looks safe in regard to wrapping. I came across this line in tasks.c which doesn’t look right:

configASSERT( xNextTaskUnblockTime >= xTickCount );

Is that right, or will it fail when xTickCount gets close to wrapping? Should it instead be:

configASSERT( ( xNextTaskUnblockTime - xTickCount ) < ( portMAX_DELAY / 2u ) );

I also see:

if( xConstTickCount >= xNextTaskUnblockTime )

Should that be:

if( ( xConstTickCount - xNextTaskUnblockTime ) < ( portMAX_DELAY / 2u ) )

I also see the code fragment if( xTickCount >= xNextTaskUnblockTime ) mentioned in comments a couple of times. The comment probably needs updating to match the code.

edwards3 wrote on Tuesday, November 15, 2016:

Looks right to me. The tick count must never be ahead of the time a task needs unblocking, and xNextTaskUnblockTime is set to ~-1 (max TickType_t value) to wait for the tick count to catch up before wrapping.