From 203057c0a554601096f70b5c3e2eea0c8e751f6e Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Wed, 10 Jul 2019 10:25:40 +0300 Subject: [PATCH] equeue - avoid Kernel::get_ms_count from IRQ Kernel::get_ms_count is documented as not working from IRQ. In RTOS builds it can return misleading answers - see https://github.com/ARM-software/CMSIS_5/issues/625 In non-RTOS builds, it can trigger an assert, as it upsets the sleep logic. Modified code is still not ideal - could be improved further if there was a fast path for "post now" that didn't bother looking at timers (both at post time and dispatch time). --- equeue_mbed.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/equeue_mbed.cpp b/equeue_mbed.cpp index 9063ee9..70e3b28 100644 --- a/equeue_mbed.cpp +++ b/equeue_mbed.cpp @@ -22,10 +22,26 @@ using namespace mbed; // Ticker operations -#if MBED_CONF_RTOS_PRESENT +#if MBED_CONF_RTOS_API_PRESENT + +#include "rtos/Kernel.h" +#include "platform/mbed_os_timer.h" unsigned equeue_tick() { - return osKernelGetTickCount(); + // It is not safe to call get_ms_count from ISRs, both + // because documentation says so, and because it will give + // a stale value from the RTOS if the interrupt has woken + // us out of sleep - the RTOS will not have updated its + // ticks yet. + if (core_util_is_isr_active()) { + // And the documentation further says that this + // should not be called from critical sections, for + // performance reasons, but I don't have a good + // current alternative! + return mbed::internal::os_timer->get_time() / 1000; + } else { + return rtos::Kernel::get_ms_count(); + } } #else