Hi, I am using FreeRTOS on the RTC and my FreeRTOS timers are called after the correct number of ticks, but the time between the ticks doesn't seem to correspond to reality.
For debugging purposes I am comparing the RTC2 to count the seconds, which I verified is accurate, and FreeRTOS with a configTICK_RATE_HZ of 100 and they don't match. FreeRTOS is a bit behind and an error accumulates over time. I am not sure what is causing the issue since the timer is triggered at the right tick count, but the number of tick is falling behind over time.
I am not sure what is causing this issue, my first reflex would be an incorrect configCPU_CLOCK_HZ, but I am using the default configuration provided by Nordic.
Setup:
- nrf52840
- S140
- SDK 15.3
- Segger Embedded Studio
- Compiling on windows.
RTC config
#define TIME_RTC NRF_RTC2 #define TIME_RTC_IRQn RTC2_IRQn #define TIME_RTC_IRQHandler RTC2_IRQHandler #define TIME_RTC_IRQ_Priority 6 #define TIME_RTC_FREQ NRFX_RTC_DEFAULT_CONFIG_FREQUENCY #define TIME_RTC_IRQ_PERIOD_MS 100 //Call IRQ every X ms. 124 is the highest possible value, less drift but at the cost of less time resolution #define TIME_RTC_PRESCALER ((TIME_RTC_FREQ*TIME_RTC_IRQ_PERIOD_MS)/1000) uint64_t rtc_ms_counter = 0; void Time_init(void) { rtc_ms_counter = 0; // Irq setup NVIC_SetPriority(TIME_RTC_IRQn, TIME_RTC_IRQ_Priority); NVIC_ClearPendingIRQ(TIME_RTC_IRQn); NVIC_EnableIRQ(TIME_RTC_IRQn); nrf_rtc_prescaler_set(TIME_RTC, round(TIME_RTC_PRESCALER)); nrf_rtc_event_enable(TIME_RTC, NRF_RTC_INT_TICK_MASK); nrf_rtc_int_enable(TIME_RTC, NRF_RTC_INT_TICK_MASK); nrf_rtc_task_trigger(TIME_RTC, NRF_RTC_TASK_START); } void TIME_RTC_IRQHandler() { nrf_rtc_event_clear(TIME_RTC, NRF_RTC_EVENT_TICK); rtc_ms_counter++; }
The timer creation
extern uint64_t rtc_ms_counter; void test_timer(){ NRF_LOG_INFO("RTOS: %d RTC: %d", xTaskGetTickCount(), rtc_ms_counter); } void timers_init(void) { TimerHandle_t m_timer = xTimerCreate("print_test", 1000/portTICK_PERIOD_MS, // convert in ms pdTRUE, NULL, test_timer); xTimerStart(m_timer, OSTIMER_WAIT_FOR_QUEUE); //Rest of code }
The relevant FreeRTOSConfig.h section
#define FREERTOS_USE_RTC 0 /**< Use real time clock for the system */ #define FREERTOS_USE_SYSTICK 1 /**< Use SysTick timer for system */ #define configTICK_SOURCE FREERTOS_USE_RTC #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_TICKLESS_IDLE 1 #define configUSE_TICKLESS_IDLE_SIMPLE_DEBUG 1 /* See into vPortSuppressTicksAndSleep source code for explanation */ #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configTICK_RATE_HZ 1000
Relevant output from the code:
<info> app: RTOS: 193006 RTC: 1943 <info> app: RTOS: 194021 RTC: 1953 <info> app: RTOS: 195003 RTC: 1963 <info> app: RTOS: 196020 RTC: 1973 <info> app: RTOS: 197001 RTC: 1983 <info> app: RTOS: 198000 RTC: 1993 <info> app: RTOS: 199001 RTC: 2003 <info> app: RTOS: 200012 RTC: 2014 <info> app: RTOS: 201013 RTC: 2024 <info> app: RTOS: 202094 RTC: 2035 <info> app: RTOS: 203000 RTC: 2044 <info> app: RTOS: 204011 RTC: 2054 <info> app: RTOS: 205038 RTC: 2064 <info> app: RTOS: 206003 RTC: 2074 <info> app: RTOS: 207001 RTC: 2084 <info> app: RTOS: 208005 RTC: 2094 <info> app: RTOS: 209022 RTC: 2104 <info> app: RTOS: 210010 RTC: 2114 <info> app: RTOS: 211000 RTC: 2124 <info> app: RTOS: 212029 RTC: 2135 <info> app: RTOS: 213027 RTC: 2145 <info> app: RTOS: 214000 RTC: 2155 <info> app: RTOS: 215000 RTC: 2165 <info> app: RTOS: 216000 RTC: 2175 <info> app: RTOS: 217000 RTC: 2185 <info> app: RTOS: 218021 RTC: 2195 <info> app: RTOS: 219007 RTC: 2205 <info> app: RTOS: 220012 RTC: 2215 <info> app: RTOS: 221000 RTC: 2225 <info> app: RTOS: 222026 RTC: 2235 <info> app: RTOS: 223000 RTC: 2245 <info> app: RTOS: 224015 RTC: 2255 <info> app: RTOS: 225019 RTC: 2266 <info> app: RTOS: 226000 RTC: 2275 <info> app: RTOS: 227000 RTC: 2285 <info> app: RTOS: 228000 RTC: 2296 <info> app: RTOS: 229004 RTC: 2306 <info> app: RTOS: 230009 RTC: 2316 <info> app: RTOS: 231000 RTC: 2326 <info> app: RTOS: 232000 RTC: 2336 <info> app: RTOS: 233000 RTC: 2346 <info> app: RTOS: 234000 RTC: 2356 <info> app: RTOS: 235015 RTC: 2366 <info> app: RTOS: 236000 RTC: 2376 <info> app: RTOS: 237000 RTC: 2386 <info> app: RTOS: 238000 RTC: 2396 <info> app: RTOS: 239016 RTC: 2406 <info> app: RTOS: 240003 RTC: 2416 <info> app: RTOS: 241001 RTC: 2426 <info> app: RTOS: 242000 RTC: 2437 <info> app: RTOS: 243017 RTC: 2447 <info> app: RTOS: 244000 RTC: 2457 <info> app: RTOS: 245001 RTC: 2467 <info> app: RTOS: 246022 RTC: 2477 <info> app: RTOS: 247000 RTC: 2487 <info> app: RTOS: 248000 RTC: 2497 <info> app: RTOS: 249006 RTC: 2507 <info> app: RTOS: 250001 RTC: 2517 <info> app: RTOS: 251000 RTC: 2527 <info> app: RTOS: 252000 RTC: 2537 <info> app: RTOS: 253001 RTC: 2547 <info> app: RTOS: 254034 RTC: 2558 <info> app: RTOS: 255000 RTC: 2567 <info> app: RTOS: 256001 RTC: 2577 <info> app: RTOS: 257000 RTC: 2588 <info> app: RTOS: 258007 RTC: 2598 <info> app: RTOS: 259037 RTC: 2608 <info> app: RTOS: 260000 RTC: 2618 <info> app: RTOS: 261000 RTC: 2628 <info> app: RTOS: 262000 RTC: 2638 <info> app: RTOS: 263000 RTC: 2648 <info> app: RTOS: 264000 RTC: 2658 <info> app: RTOS: 265000 RTC: 2668 <info> app: RTOS: 266000 RTC: 2678 <info> app: RTOS: 267000 RTC: 2688 <info> app: RTOS: 268003 RTC: 2698 <info> app: RTOS: 269000 RTC: 2708
We can see that the RTC2 ticks are increasing a bit faster than the FreeRTOS systicks. The RTC2 gets one more tick for every 5-10 timer callback, resulting in a drift between the two
As mentionned I verified the RTC2 using an external chronometer and letting both of them running for an hour. The RTC2 was still on time while the FreeRTOS systick was behind.
Any help is appreciated,
Xavier