If you do not call your function GetSysTime64() for a long time, you might miss an overflow.
With a 1000 Hz clock, the tick time overflows after 49 days, which is quiet a long time.
But mind you, there is a time tick hook, in which you can update your own tick counter:
In your example code, it would be more correct to use TickType_t in stead of uint32_t.
You’re right about the critical section, unless you have you’re on a 64-bit machine. And in that case, you wouldn’t need the extra code at all, because xTaskGetTickCount() will return a 64-bit count.
On 32bit systems reading/modifying TickType_t variables is atomic:
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
#if (portTICK_TYPE_IS_ATOMIC == 0)
/* Either variables of tick type cannot be read atomically, or
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
the tick count is returned to the standard critical section macros. */
#define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL()
#define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL()
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK_FROM_ISR((x))
#else
/* The tick type can be read atomically, so critical sections used when the
tick count is returned can be defined away. */
#define portTICK_TYPE_ENTER_CRITICAL()
#define portTICK_TYPE_EXIT_CRITICAL()
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0
#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR(x) (void)x
#endif
I’m on a 32bit system, and I need to read system time many times per second, but I need a time counter that covers more than 49 days.
So the function of my first post is perfect.
FreeRTOS already keeps track of the number of times the tick has overflowed in xNumOfOverflows, and the vTaskSetTimeOutState function will fetch the current tick count and the current overflow state, so the data is already available. The details of what vTaskSetTimeOutState gets isn’t well documented.
It also wouldn’t be hard to use the freertos_tasks_c_additions.h hook to add a function to fetch the pair as a 64 bit number.
But the values returned by it can easily be converted into the 64 bit value you want. The xNumOfOverflows is exactly what you overflow counter is, and kept by FreeRTOS in a way to prevent races.
Your function has the issue that it isn’t thread safe, and has a data race (If the first task that is calling it gets preempted after detecting the roll over but before resetting the maxTickTime, or after getting the current tick count and before testing against maxTickCount, and a tick increment occurs before some preempting task calls the function.