64-bit ticks on Cortex-M3

We’ve had a code review issue raised that our code could potentially suffer issues when the RTOS tick counter wraps around; at a tick interval of 100Hz with 32-bit ticks, this would be every 2^32 ticks, or 497 days — or 248.55 days if ticks are being subtracted (used in a signed fashion). I’d like to increase the size of TickType_t to 64 bits, i.e. “unsigned long long”. Is this likely to have any adverse side effects which would need to be addressed? Thanks, Phil.

64-bit ticks on Cortex-M3

If the review says there is something wrong in FreeRTOS, then you need to say what it is. If the review says there is something wrong in your code, then I would recommend fixing it.

64-bit ticks on Cortex-M3

Increasing the width of TickType_t sounds like postponing the problem. The tick count value is normally treated as unsigned, and taking an unsigned difference is safe: ~~~~ TickTypet xNow = xTaskGetTickCount(); TickTypet xDifference = xNow – xThen; ~~~~ Only if you need timers and time-outs that last longer that 497 days (using 100 HZ), I would consider increasing the width. The FreeRTOS kernel and libraries are fully aware that the tick-counter will have overflows. It has recently been proposed to have the tick-counter start at an unusual value like: ~~~~ /* Let xTickCount have the first overflow 5 minutes after booting. */
#define configINITIAL_TICK_COUNT_VALUE  ( ( ( TickType_t )~0u ) - pdMS_TO_TICKS( 5ul * 60000ul ) )

xTickCount = configINITIAL_TICK_COUNT_VALUE;
~~~~ This change might be usefull for testing your code. At least the overflow will occur quickly. Regards.

64-bit ticks on Cortex-M3

Only if you need timers and time-outs that last longer that 497 days (using 100 HZ), I would consider increasing the width.
…and even then it is not necessary as waking unnecessarily every 497 days in not going to impact battery life in any measurable way. You just wake, see that you timed out rather than woke due to an event, then go back to sleep for another 497 days. Using a 64-bit tick type on a 32-bit architecture is possible, but it requires a very minor code change. That is not the point though – at the moment I don’t know what the OP wishes to make this change, and if we knew that, we could provide a helpful answer.

64-bit ticks on Cortex-M3

The review stated there was an issue in our code, not FreeRTOS. We use xTaskGetTickCount() in a few places, e.g. to find out if a set period has elapsed since the last time an event occurred, using a function called “isTimeAfter” which has been posted here previously. The issue was that our implementation would fail roughly every 248.5 days, when the timer wrapped around. While the correct fix is obviously to add some kind of background task to set a “timer has expired Y/N” flag which invalidates the event flag (or to rework the code to use FreeRTOS software timers — but there was a desire not to use these because it would involve enabling another FreeRTOS build option and there was a strong desire not to do this “just for one minor feature”). The general air of the code review was that “by increasing the timer tick to 64 bits, we can avoid problems like this in the future.”

64-bit ticks on Cortex-M3

If you change the tick type to 64-bits then you will also need to edit the portmacro.h file for your port to set portTICKTYPEIS_ATOMIC to 0. However I would not recommend it, the tick type is used all over the place and making it twice the natural word size of the architecture will have a performance impact. Do these functions help your case? http://www.freertos.org/vTaskSetTimeOutState.html http://www.freertos.org/xTaskCheckForTimeOut.html The second link includes example code.

64-bit ticks on Cortex-M3

Philip, would you mind posting the source of isTimeAfter again? I can not find it.

64-bit ticks on Cortex-M3

It’s from way back in the archives: http://www.freertos.org/FreeRTOSSupportForumArchive/February2012/freertosTickcountoverflow5005076.html Apparently it was originally called timeAfter — we converted it from a function-like macro to an inline function (type checking is quite important for us from a software reliability POV) and renamed it.

64-bit ticks on Cortex-M3

I should also clarify: the specific case of this going wrong is that we were advised against using FreeRTOS Software Timers as it would require an additional Third Party Review to be done on that part of FreeRTOS, and we already had “timeAfter” reviewed. This was suggested and implemented:
  • A global variable is set to xTaskGetTickCount() + 5 minutes when event “A” occurs
  • It’s reset to five minutes when further “event A”s occur
  • It stops waiting completely (set to zero) when a different type of event (“B”) occurs
  • Other things can poll to see if the five minutes has elapsed — that is to say, event “A” has elapsed, and five minutes have elapsed without either an event “A” resetting the counter to 5 minutes again, or an event “B” to say “done waiting, too late”.
In the review, this came up: timeAfter() will return an incorrect return value when xTaskGetTickCount reaches half of its range, but event “A” hasn’t occurred yet (the global timer is still zero). If you look at it in terms of 16-bit ticks: xTaskGetTickCount = 0x7FFF GlobalTimer = 0 timeAfter = (GlobalTimer – 0x7FFF) = 0x8001 = TRUE timeAfter = (GlobalTimer – 0x8000) = 0x8000 = TRUE timeAfter = (GlobalTimer – 0x8001) = 0x7FFF = FALSE timeAfter = (GlobalTimer – 0x8002) = 0x7FFE = FALSE The same holds if this is extended to 32-bit ticks.