64 bit system time using 32bit TickCount

~~~ uint64t GetSysTime64() { static uint64t systime = 0; static uint32t maxticktime = 0; static uint32t overflow = 0; uint32_t ticktime;
ticktime = xTaskGetTickCount();

if (ticktime < maxticktime) overflow++;
maxticktime = ticktime;

systime = overflow;
systime <<= 32;
systime += ticktime;
return systime;
} ~~~

64 bit system time using 32bit TickCount

systime” doesn’t have to be static 🙂 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: ~~~

if( configUSETICKHOOK != 0 )

volatile uint64_t tickCount64;
void vApplicationTickHook( void )
{
    tickCount64++;
}

endif /* configUSETICKHOOK */

~~~ The above code won’t miss a single clock tick

64 bit system time using 32bit TickCount

I didn’t remember configUSETICKHOOK… Anyway you need a mutex to read/write tickCount64, or: ~~~ uint64t GetTickCount64() { uint64 tick; taskENTERCRITICAL(); tick = tickCount64; taskEXITCRITICAL(); return tick; } ~~~

64 bit system time using 32bit TickCount

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.

64 bit system time using 32bit TickCount

Not sure what is trying to be achieved here, but the kernel code already keeps a count of the number of overflows if that is helpful: https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/tasks.c#l373 If you want access to it you can add your own code into tasks.c using the c additions header file: https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/tasks.c#l5203

64 bit system time using 32bit TickCount

One more addition about the atomical copy of TickType_t: ~~~ TickTypet xTaskGetTickCount( void ) { TickTypet xTicks;
/* Critical section required if running on a 16 bit processor. */
portTICK_TYPE_ENTER_CRITICAL();
{
    xTicks = xTickCount;
}
portTICK_TYPE_EXIT_CRITICAL();

return xTicks;
} ~~~ With the above code, a critical section will be entered only if needed.

64 bit system time using 32bit TickCount

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 portTICKTYPEIS_ATOMIC 1

endif

~~~ ~~~

if (portTICKTYPEIS_ATOMIC == 0)

/* Either variables of tick type cannot be read atomically, or portTICKTYPEIS_ATOMIC was not set – map the critical sections used when the tick count is returned to the standard critical section macros. */

define portTICKTYPEENTERCRITICAL() portENTERCRITICAL()

define portTICKTYPEEXITCRITICAL() portEXITCRITICAL()

define portTICKTYPESETINTERRUPTMASKFROMISR() portSETINTERRUPTMASKFROMISR()

define portTICKTYPECLEARINTERRUPTMASKFROMISR(x) portCLEARINTERRUPTMASKFROMISR((x))

else

/* The tick type can be read atomically, so critical sections used when the tick count is returned can be defined away. */

define portTICKTYPEENTER_CRITICAL()

define portTICKTYPEEXIT_CRITICAL()

define portTICKTYPESETINTERRUPTMASKFROMISR() 0

define portTICKTYPECLEARINTERRUPTMASKFROMISR(x) (void)x

endif

~~~

64 bit system time using 32bit TickCount

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.

64 bit system time using 32bit TickCount

Yes, but this overflow count is more for internal use, and I prefer not to modify FreeRTOS source files.

64 bit system time using 32bit TickCount

The point of the C inclusions header file is that you can add code into the task.c file WITHOUT modifying the kernel code.

64 bit system time using 32bit TickCount

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 freertostasksc_additions.h hook to add a function to fetch the pair as a 64 bit number.

64 bit system time using 32bit TickCount

For my apllication I nedd an absolute 64bit time counter. vTaskSetTimeOutState doesn’t work well for me.

64 bit system time using 32bit TickCount

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.

64 bit system time using 32bit TickCount

I don’t need thread safe, only one task calls this function. Anyway I can use taskENTER_CRITICAL.