@@ -40,24 +40,64 @@ constexpr uint32_t kTicksOverflowShift = (configUSE_16_BIT_TICKS) ? 16 : 32;
4040
4141uint64_t sBootTimeUS = 0 ;
4242
43- uint64_t TicksSinceBoot (void )
43+ #ifdef __CORTEX_M
44+ BaseType_t sNumOfOverflows ;
45+ #endif
46+ } // unnamed namespace
47+
48+ /* *
49+ * Returns the number of FreeRTOS ticks since the system booted.
50+ *
51+ * NOTE: The default implementation of this function uses FreeRTOS's
52+ * vTaskSetTimeOutState() function to get the total number of ticks,
53+ * irrespective of tick counter overflows. Unfortunately, this function cannot
54+ * be called in interrupt context, no equivalent ISR function exists, and
55+ * FreeRTOS provides no portable way of determining whether a function is being
56+ * called in an interrupt context. Adaptations that need to use the Weave
57+ * Get/SetClock methods from within an interrupt handler must override this
58+ * function with a suitable alternative that works on the target platform. The
59+ * provided version is safe to call on ARM Cortex platforms with CMSIS
60+ * libraries.
61+ */
62+
63+ uint64_t FreeRTOSTicksSinceBoot (void ) __attribute__((weak));
64+
65+ uint64_t FreeRTOSTicksSinceBoot (void )
4466{
4567 TimeOut_t timeOut;
68+
69+ #ifdef __CORTEX_M
70+ if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) // running in an interrupt context
71+ {
72+ // Note that sNumOverflows may be quite stale, and under those
73+ // circumstances, the function may violate monotonicity guarantees
74+ timeout.xTimeOnEntering = xTaskGetTickCountFromISR ();
75+ timeout.xOverflowCount = sNumOfOverflows ;
76+ }
77+ else
78+ {
79+ #endif
80+
4681 vTaskSetTimeOutState (&timeOut);
82+
83+ #ifdef __CORTEX_M
84+ // BaseType_t is supposed to be atomic
85+ sNumOfOverflows = timeOut.xOverflowCount ;
86+ }
87+ #endif
88+
4789 return static_cast <uint64_t >(timeOut.xTimeOnEntering ) +
4890 (static_cast <uint64_t >(timeOut.xOverflowCount ) << kTicksOverflowShift );
4991}
5092
51- } // unnamed namespace
52-
5393uint64_t GetClock_Monotonic (void )
5494{
55- return (TicksSinceBoot () * kMicrosecondsPerSecond ) / configTICK_RATE_HZ;
95+ return (FreeRTOSTicksSinceBoot () * kMicrosecondsPerSecond ) / configTICK_RATE_HZ;
5696}
5797
5898uint64_t GetClock_MonotonicMS (void )
5999{
60- return (TicksSinceBoot () * kMillisecondPerSecond ) / configTICK_RATE_HZ;
100+ return (FreeRTOSTicksSinceBoot () * kMillisecondPerSecond ) / configTICK_RATE_HZ;
61101}
62102
63103uint64_t GetClock_MonotonicHiRes (void )
0 commit comments