From 274791635fb0fda9ac11aa9c1999fc710ed36a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Zi=C4=99cik?= Date: Fri, 3 Aug 2018 14:57:29 +0200 Subject: [PATCH] drivers: timer: nrf: Optimize k_cycle_get_32(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous implementation of _timer_cycle_get_32() (which is directly mapped to k_cycle_get_32()) taken from 87 to 132 cycles. As result it was too heavy for using it as source of time for logger. This commit makes this function faster by removing redundant access to the RTC register (each access consumed 28 CPU cycles) as well as loop, which made this call non-deterministic. After these changes the k_cycle_get_32() needs only 50-52 cycles in to calculate 32-bit timestamp. Signed-off-by: Piotr Zięcik --- drivers/timer/nrf_rtc_timer.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c index 7415093abe2220..3cd9518322321a 100644 --- a/drivers/timer/nrf_rtc_timer.c +++ b/drivers/timer/nrf_rtc_timer.c @@ -550,24 +550,27 @@ int _sys_clock_driver_init(struct device *device) u32_t _timer_cycle_get_32(void) { + u32_t ticked_cycles; u32_t elapsed_cycles; - u32_t sys_clock_tick_count; - u32_t rtc_prev; - u32_t rtc_now; - rtc_now = RTC_COUNTER; - /* Discard value of RTC_COUNTER read at LFCLK transition */ - do { - sys_clock_tick_count = _sys_clock_tick_count; - elapsed_cycles = (rtc_now - (sys_clock_tick_count * - sys_clock_hw_cycles_per_tick)) & - RTC_MASK; - rtc_prev = rtc_now; - rtc_now = RTC_COUNTER; - } while (rtc_now != rtc_prev); + /* Number of timer cycles announced as ticks so far. */ + ticked_cycles = _sys_clock_tick_count * sys_clock_hw_cycles_per_tick; + + /* Make sure that compiler will not reverse access to RTC and + * _sys_clock_tick_count + */ + compiler_barrier(); + + /* Number of timer cycles since last announced tick we know about. + * + * The value of RTC_COUNTER is not reset on tick, so it will + * compensate potentialy missed update of _sys_clock_tick_count + * which could have happen between the ticked_cycles calculation + * and the code below. + */ + elapsed_cycles = (RTC_COUNTER - ticked_cycles) & RTC_MASK; - return (sys_clock_tick_count * sys_clock_hw_cycles_per_tick) + - elapsed_cycles; + return ticked_cycles + elapsed_cycles; } #ifdef CONFIG_SYSTEM_CLOCK_DISABLE