cyclic: Fix rollover every 72 min on 32 bits platforms
authorPatrice Chotard <patrice.chotard@foss.st.com>
Tue, 14 Jan 2025 13:28:13 +0000 (14:28 +0100)
committerStefan Roese <sr@denx.de>
Wed, 22 Jan 2025 09:22:34 +0000 (10:22 +0100)
On 32 bits platforms, timer_get_us() returns an unsigned long which
is a 32 bits. timer_get_us() wraps around every 72 minutes
(2 ^ 32 / 1000000 =~ 4295 sec =~ 72 min).

So the test "if time_after_eq64(now, cyclic->next_call)" is no more
true when cyclic->next_call becomes above 32 bits max value (4294967295).

At this point after 72 min, no more cyclic function are
executed included watchdog one.

Instead of using timer_get_us(), use get_timer_us() which returns a
uint64_t, this allows a rollover every 584942 years.

Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
Reviewed-by: Stefan Roese <sr@denx.de>
common/cyclic.c

index 196797f..fad071a 100644 (file)
@@ -36,7 +36,7 @@ void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
        cyclic->func = func;
        cyclic->name = name;
        cyclic->delay_us = delay_us;
-       cyclic->start_time_us = timer_get_us();
+       cyclic->start_time_us = get_timer_us(0);
        hlist_add_head(&cyclic->list, cyclic_get_list());
 }
 
@@ -61,13 +61,13 @@ static void cyclic_run(void)
                 * Check if this cyclic function needs to get called, e.g.
                 * do not call the cyclic func too often
                 */
-               now = timer_get_us();
+               now = get_timer_us(0);
                if (time_after_eq64(now, cyclic->next_call)) {
                        /* Call cyclic function and account it's cpu-time */
                        cyclic->next_call = now + cyclic->delay_us;
                        cyclic->func(cyclic);
                        cyclic->run_cnt++;
-                       cpu_time = timer_get_us() - now;
+                       cpu_time = get_timer_us(0) - now;
                        cyclic->cpu_time_us += cpu_time;
 
                        /* Check if cpu-time exceeds max allowed time */