25
25
26
26
#include " hal/lp_ticker_api.h"
27
27
#include " mbed_critical.h"
28
+ #include " mbed_assert.h"
28
29
#if defined(TARGET_CORTEX_A)
29
30
#include " rtx_core_ca.h"
30
31
#else // Cortex-M
@@ -37,6 +38,9 @@ extern "C" {
37
38
#endif
38
39
}
39
40
41
+ #define US_IN_TICK (1000000 / OS_TICK_FREQ)
42
+ MBED_STATIC_ASSERT (1000000 % OS_TICK_FREQ == 0 , " OS_TICK_FREQ must be a divisor of 1000000 for correct tick calculations" );
43
+
40
44
#if (defined(NO_SYSTICK))
41
45
/* *
42
46
* Return an IRQ number that can be used in the absence of SysTick
@@ -54,17 +58,17 @@ namespace rtos {
54
58
namespace internal {
55
59
56
60
SysTimer::SysTimer () :
57
- TimerEvent (get_lp_ticker_data()), _start_time (0 ), _tick(0 )
61
+ TimerEvent (get_lp_ticker_data()), _time_us (0 ), _tick(0 )
58
62
{
59
- _start_time = ticker_read_us (_ticker_data);
63
+ _time_us = ticker_read_us (_ticker_data);
60
64
_suspend_time_passed = true ;
61
65
_suspended = false ;
62
66
}
63
67
64
68
SysTimer::SysTimer (const ticker_data_t *data) :
65
- TimerEvent (data), _start_time (0 ), _tick(0 )
69
+ TimerEvent (data), _time_us (0 ), _tick(0 )
66
70
{
67
- _start_time = ticker_read_us (_ticker_data);
71
+ _time_us = ticker_read_us (_ticker_data);
68
72
}
69
73
70
74
void SysTimer::setup_irq ()
@@ -106,16 +110,16 @@ uint32_t SysTimer::resume()
106
110
_suspend_time_passed = true ;
107
111
remove ();
108
112
109
- uint64_t new_tick = (ticker_read_us (_ticker_data) - _start_time) * OS_TICK_FREQ / 1000000 ;
110
- if (new_tick > _tick ) {
113
+ uint64_t elapsed_ticks = (ticker_read_us (_ticker_data) - _time_us) / US_IN_TICK ;
114
+ if (elapsed_ticks > 0 ) {
111
115
// Don't update to the current tick. Instead, update to the
112
116
// previous tick and let the SysTick handler increment it
113
117
// to the current value. This allows scheduling restart
114
118
// successfully after the OS is resumed.
115
- new_tick --;
119
+ elapsed_ticks --;
116
120
}
117
- uint32_t elapsed_ticks = new_tick - _tick ;
118
- _tick = new_tick ;
121
+ _time_us += elapsed_ticks * US_IN_TICK ;
122
+ _tick += elapsed_ticks ;
119
123
120
124
core_util_critical_section_exit ();
121
125
return elapsed_ticks;
@@ -125,7 +129,7 @@ void SysTimer::schedule_tick(uint32_t delta)
125
129
{
126
130
core_util_critical_section_enter ();
127
131
128
- insert_absolute (_start_time + (_tick + delta) * 1000000ULL / OS_TICK_FREQ );
132
+ insert_absolute (_time_us + delta * US_IN_TICK );
129
133
130
134
core_util_critical_section_exit ();
131
135
}
@@ -171,6 +175,7 @@ void SysTimer::_increment_tick()
171
175
// Protected function synchronized externally
172
176
173
177
_tick++;
178
+ _time_us += US_IN_TICK;
174
179
}
175
180
176
181
void SysTimer::handler ()
0 commit comments