ticktime = xTaskGetTickCount();
if (ticktime < maxticktime) overflow++;
maxticktime = ticktime;
systime = overflow;
systime <<= 32;
systime += ticktime;
return systime;
}
~~~
64 bit system time using 32bit TickCount
~~~
uint64t GetSysTime64()
{
static uint64t systime = 0;
static uint32t maxticktime = 0;
static uint32t overflow = 0;
uint32_t ticktime;
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 tick64 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.