GRTC is not cleared on reset, causes Zephyr sys_clock to break when uptime > 20 hours

By default the GRTC peripheral is not cleared when started via sys_clock_driver_init. This is because nrfx_grtc_init calls nrfy_grtc_prepare, however NRFX_GRTC_CONFIG_CLEAR_AT_INIT is not set and therefore the NRF_GRTC_TASK_CLEAR is not triggered. Most obviously this means that the uptime shown in the logs will not reset.

More importantly, the first time sys_clock_timeout_handler fires it will have a very large cc_val and a last_count value of 0. For a boot ~20 hours after the initial power-on reset the computed value of dticks will be greater than INT_MAX and will overflow the int32_t parameter passed to sys_clock_announce. This can lead to several behaviors, but the simplest is that the ticks parameter is interpreted as a negative number which underflows the uint64_t curr_tick. This leads to huge values returned by sys_clock_tick_get (and similar functions) and causes all kernel timers to stop firing.

In my opinion the correct fix is to simply reset the GRTC peripheral on boot, the same as the RTC driver did. This can be done by adding a config NRF_GRTC_CLEAR_AT_INIT to Kconfig.nrf_grtc (ideally default y if NRF_GRTC_START_SYSCOUNTER). Then just add the associated bit in nrfx_kconfig.h.

#ifdef CONFIG_NRF_GRTC_CLEAR_AT_INIT
#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 1
#endif

Related