Skip to content

Commit 3352b43

Browse files
author
Cruz Monrreal
authored
Merge pull request #9786 from c1728p9/tickless_optimization
Optimize tickless tick computation
2 parents e1736cd + f6ed7ce commit 3352b43

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

rtos/TARGET_CORTEX/SysTimer.cpp

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "hal/lp_ticker_api.h"
2727
#include "mbed_critical.h"
28+
#include "mbed_assert.h"
2829
#if defined(TARGET_CORTEX_A)
2930
#include "rtx_core_ca.h"
3031
#else//Cortex-M
@@ -37,6 +38,9 @@ extern "C" {
3738
#endif
3839
}
3940

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+
4044
#if (defined(NO_SYSTICK))
4145
/**
4246
* Return an IRQ number that can be used in the absence of SysTick
@@ -54,17 +58,17 @@ namespace rtos {
5458
namespace internal {
5559

5660
SysTimer::SysTimer() :
57-
TimerEvent(get_lp_ticker_data()), _start_time(0), _tick(0)
61+
TimerEvent(get_lp_ticker_data()), _time_us(0), _tick(0)
5862
{
59-
_start_time = ticker_read_us(_ticker_data);
63+
_time_us = ticker_read_us(_ticker_data);
6064
_suspend_time_passed = true;
6165
_suspended = false;
6266
}
6367

6468
SysTimer::SysTimer(const ticker_data_t *data) :
65-
TimerEvent(data), _start_time(0), _tick(0)
69+
TimerEvent(data), _time_us(0), _tick(0)
6670
{
67-
_start_time = ticker_read_us(_ticker_data);
71+
_time_us = ticker_read_us(_ticker_data);
6872
}
6973

7074
void SysTimer::setup_irq()
@@ -83,14 +87,13 @@ void SysTimer::setup_irq()
8387

8488
void SysTimer::suspend(uint32_t ticks)
8589
{
86-
core_util_critical_section_enter();
87-
90+
// Remove ensures serialized access to SysTimer by stopping timer interrupt
8891
remove();
89-
schedule_tick(ticks);
92+
9093
_suspend_time_passed = false;
9194
_suspended = true;
9295

93-
core_util_critical_section_exit();
96+
schedule_tick(ticks);
9497
}
9598

9699
bool SysTimer::suspend_time_passed()
@@ -100,43 +103,40 @@ bool SysTimer::suspend_time_passed()
100103

101104
uint32_t SysTimer::resume()
102105
{
103-
core_util_critical_section_enter();
106+
// Remove ensures serialized access to SysTimer by stopping timer interrupt
107+
remove();
104108

105109
_suspended = false;
106110
_suspend_time_passed = true;
107-
remove();
108111

109-
uint64_t new_tick = (ticker_read_us(_ticker_data) - _start_time) * OS_TICK_FREQ / 1000000;
110-
if (new_tick > _tick) {
112+
uint64_t elapsed_ticks = (ticker_read_us(_ticker_data) - _time_us) / US_IN_TICK;
113+
if (elapsed_ticks > 0) {
111114
// Don't update to the current tick. Instead, update to the
112115
// previous tick and let the SysTick handler increment it
113116
// to the current value. This allows scheduling restart
114117
// successfully after the OS is resumed.
115-
new_tick--;
118+
elapsed_ticks--;
116119
}
117-
uint32_t elapsed_ticks = new_tick - _tick;
118-
_tick = new_tick;
120+
_time_us += elapsed_ticks * US_IN_TICK;
121+
_tick += elapsed_ticks;
119122

120-
core_util_critical_section_exit();
121123
return elapsed_ticks;
122124
}
123125

124126
void SysTimer::schedule_tick(uint32_t delta)
125127
{
126128
core_util_critical_section_enter();
127129

128-
insert_absolute(_start_time + (_tick + delta) * 1000000ULL / OS_TICK_FREQ);
130+
insert_absolute(_time_us + delta * US_IN_TICK);
129131

130132
core_util_critical_section_exit();
131133
}
132134

133135
void SysTimer::cancel_tick()
134136
{
135-
core_util_critical_section_enter();
137+
// Underlying call is interrupt safe
136138

137139
remove();
138-
139-
core_util_critical_section_exit();
140140
}
141141

142142
uint32_t SysTimer::get_tick()
@@ -146,6 +146,8 @@ uint32_t SysTimer::get_tick()
146146

147147
us_timestamp_t SysTimer::get_time()
148148
{
149+
// Underlying call is interrupt safe
150+
149151
return ticker_read_us(_ticker_data);
150152
}
151153

@@ -171,6 +173,7 @@ void SysTimer::_increment_tick()
171173
// Protected function synchronized externally
172174

173175
_tick++;
176+
_time_us += US_IN_TICK;
174177
}
175178

176179
void SysTimer::handler()

rtos/TARGET_CORTEX/SysTimer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class SysTimer: private mbed::TimerEvent, private mbed::NonCopyable<SysTimer> {
117117
virtual void handler();
118118
void _increment_tick();
119119
static void _set_irq_pending();
120-
us_timestamp_t _start_time;
120+
us_timestamp_t _time_us;
121121
uint64_t _tick;
122122
bool _suspend_time_passed;
123123
bool _suspended;

0 commit comments

Comments
 (0)