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 :-)
Thanks, Martin
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 configUSETICKLESSIDLE 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.
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. */
~~~ 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.
If it is useful to people I will add something similar to the FreeRTOS code.
Set configUSE16BIT_TICKS to 0, then the tick will overflow every few seconds.
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.
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.