mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #9786 from c1728p9/tickless_optimization
Optimize tickless tick computationpull/9856/head
commit
3352b431b3
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "hal/lp_ticker_api.h"
|
#include "hal/lp_ticker_api.h"
|
||||||
#include "mbed_critical.h"
|
#include "mbed_critical.h"
|
||||||
|
#include "mbed_assert.h"
|
||||||
#if defined(TARGET_CORTEX_A)
|
#if defined(TARGET_CORTEX_A)
|
||||||
#include "rtx_core_ca.h"
|
#include "rtx_core_ca.h"
|
||||||
#else//Cortex-M
|
#else//Cortex-M
|
||||||
|
@ -37,6 +38,9 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define US_IN_TICK (1000000 / OS_TICK_FREQ)
|
||||||
|
MBED_STATIC_ASSERT(1000000 % OS_TICK_FREQ == 0, "OS_TICK_FREQ must be a divisor of 1000000 for correct tick calculations");
|
||||||
|
|
||||||
#if (defined(NO_SYSTICK))
|
#if (defined(NO_SYSTICK))
|
||||||
/**
|
/**
|
||||||
* Return an IRQ number that can be used in the absence of SysTick
|
* Return an IRQ number that can be used in the absence of SysTick
|
||||||
|
@ -54,17 +58,17 @@ namespace rtos {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
SysTimer::SysTimer() :
|
SysTimer::SysTimer() :
|
||||||
TimerEvent(get_lp_ticker_data()), _start_time(0), _tick(0)
|
TimerEvent(get_lp_ticker_data()), _time_us(0), _tick(0)
|
||||||
{
|
{
|
||||||
_start_time = ticker_read_us(_ticker_data);
|
_time_us = ticker_read_us(_ticker_data);
|
||||||
_suspend_time_passed = true;
|
_suspend_time_passed = true;
|
||||||
_suspended = false;
|
_suspended = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SysTimer::SysTimer(const ticker_data_t *data) :
|
SysTimer::SysTimer(const ticker_data_t *data) :
|
||||||
TimerEvent(data), _start_time(0), _tick(0)
|
TimerEvent(data), _time_us(0), _tick(0)
|
||||||
{
|
{
|
||||||
_start_time = ticker_read_us(_ticker_data);
|
_time_us = ticker_read_us(_ticker_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysTimer::setup_irq()
|
void SysTimer::setup_irq()
|
||||||
|
@ -83,14 +87,13 @@ void SysTimer::setup_irq()
|
||||||
|
|
||||||
void SysTimer::suspend(uint32_t ticks)
|
void SysTimer::suspend(uint32_t ticks)
|
||||||
{
|
{
|
||||||
core_util_critical_section_enter();
|
// Remove ensures serialized access to SysTimer by stopping timer interrupt
|
||||||
|
|
||||||
remove();
|
remove();
|
||||||
schedule_tick(ticks);
|
|
||||||
_suspend_time_passed = false;
|
_suspend_time_passed = false;
|
||||||
_suspended = true;
|
_suspended = true;
|
||||||
|
|
||||||
core_util_critical_section_exit();
|
schedule_tick(ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SysTimer::suspend_time_passed()
|
bool SysTimer::suspend_time_passed()
|
||||||
|
@ -100,24 +103,23 @@ bool SysTimer::suspend_time_passed()
|
||||||
|
|
||||||
uint32_t SysTimer::resume()
|
uint32_t SysTimer::resume()
|
||||||
{
|
{
|
||||||
core_util_critical_section_enter();
|
// Remove ensures serialized access to SysTimer by stopping timer interrupt
|
||||||
|
remove();
|
||||||
|
|
||||||
_suspended = false;
|
_suspended = false;
|
||||||
_suspend_time_passed = true;
|
_suspend_time_passed = true;
|
||||||
remove();
|
|
||||||
|
|
||||||
uint64_t new_tick = (ticker_read_us(_ticker_data) - _start_time) * OS_TICK_FREQ / 1000000;
|
uint64_t elapsed_ticks = (ticker_read_us(_ticker_data) - _time_us) / US_IN_TICK;
|
||||||
if (new_tick > _tick) {
|
if (elapsed_ticks > 0) {
|
||||||
// Don't update to the current tick. Instead, update to the
|
// Don't update to the current tick. Instead, update to the
|
||||||
// previous tick and let the SysTick handler increment it
|
// previous tick and let the SysTick handler increment it
|
||||||
// to the current value. This allows scheduling restart
|
// to the current value. This allows scheduling restart
|
||||||
// successfully after the OS is resumed.
|
// successfully after the OS is resumed.
|
||||||
new_tick--;
|
elapsed_ticks--;
|
||||||
}
|
}
|
||||||
uint32_t elapsed_ticks = new_tick - _tick;
|
_time_us += elapsed_ticks * US_IN_TICK;
|
||||||
_tick = new_tick;
|
_tick += elapsed_ticks;
|
||||||
|
|
||||||
core_util_critical_section_exit();
|
|
||||||
return elapsed_ticks;
|
return elapsed_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,18 +127,16 @@ void SysTimer::schedule_tick(uint32_t delta)
|
||||||
{
|
{
|
||||||
core_util_critical_section_enter();
|
core_util_critical_section_enter();
|
||||||
|
|
||||||
insert_absolute(_start_time + (_tick + delta) * 1000000ULL / OS_TICK_FREQ);
|
insert_absolute(_time_us + delta * US_IN_TICK);
|
||||||
|
|
||||||
core_util_critical_section_exit();
|
core_util_critical_section_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysTimer::cancel_tick()
|
void SysTimer::cancel_tick()
|
||||||
{
|
{
|
||||||
core_util_critical_section_enter();
|
// Underlying call is interrupt safe
|
||||||
|
|
||||||
remove();
|
remove();
|
||||||
|
|
||||||
core_util_critical_section_exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SysTimer::get_tick()
|
uint32_t SysTimer::get_tick()
|
||||||
|
@ -146,6 +146,8 @@ uint32_t SysTimer::get_tick()
|
||||||
|
|
||||||
us_timestamp_t SysTimer::get_time()
|
us_timestamp_t SysTimer::get_time()
|
||||||
{
|
{
|
||||||
|
// Underlying call is interrupt safe
|
||||||
|
|
||||||
return ticker_read_us(_ticker_data);
|
return ticker_read_us(_ticker_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +173,7 @@ void SysTimer::_increment_tick()
|
||||||
// Protected function synchronized externally
|
// Protected function synchronized externally
|
||||||
|
|
||||||
_tick++;
|
_tick++;
|
||||||
|
_time_us += US_IN_TICK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysTimer::handler()
|
void SysTimer::handler()
|
||||||
|
|
|
@ -117,7 +117,7 @@ protected:
|
||||||
virtual void handler();
|
virtual void handler();
|
||||||
void _increment_tick();
|
void _increment_tick();
|
||||||
static void _set_irq_pending();
|
static void _set_irq_pending();
|
||||||
us_timestamp_t _start_time;
|
us_timestamp_t _time_us;
|
||||||
uint64_t _tick;
|
uint64_t _tick;
|
||||||
bool _suspend_time_passed;
|
bool _suspend_time_passed;
|
||||||
bool _suspended;
|
bool _suspended;
|
||||||
|
|
Loading…
Reference in New Issue