From cfda30bd57f7c59531bba7aa477cc85f08cbd039 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Mon, 23 Jan 2023 14:31:32 +0100 Subject: [PATCH] Extend os_get_current_time_us bits tick_to_ms is not guaranteed to wrap at 32bit boundary if tick speed is not set to 1ms per tick. It will also regress to low precision (1second) when the tick count is larger than UINT32_MAX / 1000. --- src/rt-kernel/osal.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/rt-kernel/osal.c b/src/rt-kernel/osal.c index 2b82d0a..eaddc4c 100644 --- a/src/rt-kernel/osal.c +++ b/src/rt-kernel/osal.c @@ -14,6 +14,10 @@ ********************************************************************/ #include "osal.h" +#include "kern/types.h" +#include "kern/int.h" + +extern const os_cfg_t os_cfg; void * os_malloc (size_t size) { @@ -60,9 +64,38 @@ void os_usleep (uint32_t us) task_delay (tick_from_ms (us / 1000)); } +/** + * \brief Extend kernel tick to 64 bits without wrap + * + * \return uint64_t number of ticks since start + */ +static uint64_t os_get_current_tick (void) +{ + static volatile tick_t os_tick_last = 0u; + static volatile uint64_t os_tick_base = 0u; + tick_t tick; + tick_t last; + uint64_t base; + + int_lock(); + last = os_tick_last; + base = os_tick_base; + tick = tick_get(); + if (tick < last) + { + base += 1ull + UINT32_MAX; + } + os_tick_last = tick; + os_tick_base = base; + int_unlock(); + + return base + tick; +} + uint32_t os_get_current_time_us (void) { - return 1000 * tick_to_ms (tick_get()); + uint64_t us = 10000000ull * os_get_current_tick() / os_cfg.ticks_per_second; + return (uint32_t)us; } os_sem_t * os_sem_create (size_t count)