Merge pull request #12903 from kjbracey-arm/chrono_ns

Nanostack HAL: Convert to Chrono
pull/12977/head
Martin Kojtal 2020-05-15 08:21:41 +02:00 committed by GitHub
commit e48a659f81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 43 deletions

View File

@ -23,7 +23,7 @@
#include "mbed_trace.h" #include "mbed_trace.h"
#include "platform/SingletonPtr.h" #include "platform/SingletonPtr.h"
#include "platform/arm_hal_interrupt.h" #include "platform/arm_hal_interrupt.h"
#include <Timer.h> #include "platform/mbed_power_mgmt.h"
#include "equeue.h" #include "equeue.h"
#include "events/EventQueue.h" #include "events/EventQueue.h"
#include "mbed_shared_queues.h" #include "mbed_shared_queues.h"
@ -37,8 +37,9 @@
namespace { namespace {
using namespace mbed; using namespace mbed;
using namespace events; using namespace events;
using namespace std::chrono;
using std::micro;
static SingletonPtr<Timer> timer;
static bool timer_initialized = false; static bool timer_initialized = false;
static const fhss_api_t *fhss_active_handle = NULL; static const fhss_api_t *fhss_active_handle = NULL;
#if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT #if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
@ -53,45 +54,41 @@ static EventQueue *equeue;
// an initialized-data cost. // an initialized-data cost.
struct fhss_timeout_s { struct fhss_timeout_s {
void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t) = nullptr; void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t) = nullptr;
uint32_t start_time = 0;
uint32_t stop_time = 0;
bool active = false; bool active = false;
SingletonPtr<Timeout> timeout; SingletonPtr<Timeout> timeout;
}; };
fhss_timeout_s fhss_timeout[NUMBER_OF_SIMULTANEOUS_TIMEOUTS]; fhss_timeout_s fhss_timeout[NUMBER_OF_SIMULTANEOUS_TIMEOUTS];
static uint32_t read_current_time(void)
{
return timer->read_us();
}
static fhss_timeout_s *find_timeout(void (*callback)(const fhss_api_t *api, uint16_t)) static fhss_timeout_s *find_timeout(void (*callback)(const fhss_api_t *api, uint16_t))
{ {
for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) { for (fhss_timeout_s &t : fhss_timeout) {
if (fhss_timeout[i].fhss_timer_callback == callback) { if (t.fhss_timer_callback == callback) {
return &fhss_timeout[i]; return &t;
} }
} }
return NULL; return nullptr;
} }
static fhss_timeout_s *allocate_timeout(void) static fhss_timeout_s *allocate_timeout(void)
{ {
for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) { for (fhss_timeout_s &t : fhss_timeout) {
if (fhss_timeout[i].fhss_timer_callback == NULL) { if (t.fhss_timer_callback == NULL) {
return &fhss_timeout[i]; return &t;
} }
} }
return NULL; return nullptr;
} }
static void fhss_timeout_handler(void) static void fhss_timeout_handler(void)
{ {
for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) { for (fhss_timeout_s &t : fhss_timeout) {
if (fhss_timeout[i].active && ((fhss_timeout[i].stop_time - fhss_timeout[i].start_time) <= (read_current_time() - fhss_timeout[i].start_time))) { if (t.active) {
fhss_timeout[i].active = false; microseconds remaining_time = t.timeout->remaining_time();
fhss_timeout[i].fhss_timer_callback(fhss_active_handle, read_current_time() - fhss_timeout[i].stop_time); if (remaining_time <= 0s) {
t.active = false;
t.fhss_timer_callback(fhss_active_handle, -remaining_time.count());
}
} }
} }
} }
@ -114,7 +111,7 @@ static int platform_fhss_timer_start(uint32_t slots, void (*callback)(const fhss
equeue = mbed_highprio_event_queue(); equeue = mbed_highprio_event_queue();
MBED_ASSERT(equeue != NULL); MBED_ASSERT(equeue != NULL);
#endif #endif
timer->start(); HighResClock::lock();
timer_initialized = true; timer_initialized = true;
} }
fhss_timeout_s *fhss_tim = find_timeout(callback); fhss_timeout_s *fhss_tim = find_timeout(callback);
@ -127,10 +124,8 @@ static int platform_fhss_timer_start(uint32_t slots, void (*callback)(const fhss
return ret_val; return ret_val;
} }
fhss_tim->fhss_timer_callback = callback; fhss_tim->fhss_timer_callback = callback;
fhss_tim->start_time = read_current_time();
fhss_tim->stop_time = fhss_tim->start_time + slots;
fhss_tim->active = true; fhss_tim->active = true;
fhss_tim->timeout->attach_us(timer_callback, slots); fhss_tim->timeout->attach(timer_callback, microseconds{slots});
fhss_active_handle = callback_param; fhss_active_handle = callback_param;
ret_val = 0; ret_val = 0;
platform_exit_critical(); platform_exit_critical();
@ -161,18 +156,19 @@ static uint32_t platform_fhss_get_remaining_slots(void (*callback)(const fhss_ap
platform_exit_critical(); platform_exit_critical();
return 0; return 0;
} }
uint32_t remaining_slots = fhss_tim->stop_time - read_current_time(); microseconds remaining_slots = fhss_tim->timeout->remaining_time();
platform_exit_critical(); platform_exit_critical();
return remaining_slots; return remaining_slots.count();
} }
static uint32_t platform_fhss_timestamp_read(const fhss_api_t *api) static uint32_t platform_fhss_timestamp_read(const fhss_api_t *api)
{ {
(void)api; (void)api;
return read_current_time(); return HighResClock::now().time_since_epoch().count();
} }
} // anonymous namespace } // anonymous namespace
static_assert(std::ratio_equal<HighResClock::period, micro>::value, "HighResClock not microseconds!");
fhss_timer_t fhss_functions = { fhss_timer_t fhss_functions = {
.fhss_timer_start = platform_fhss_timer_start, .fhss_timer_start = platform_fhss_timer_start,
.fhss_timer_stop = platform_fhss_timer_stop, .fhss_timer_stop = platform_fhss_timer_stop,

View File

@ -23,15 +23,16 @@
#include "platform/arm_hal_interrupt.h" #include "platform/arm_hal_interrupt.h"
#include "platform/mbed_assert.h" #include "platform/mbed_assert.h"
#include "Timeout.h" #include "Timeout.h"
#include "Timer.h"
#include "Ticker.h"
#include "events/Event.h" #include "events/Event.h"
#include "events/mbed_shared_queues.h" #include "events/mbed_shared_queues.h"
using namespace mbed; using namespace mbed;
using namespace events; using namespace events;
using std::ratio;
using std::milli;
using std::micro;
using namespace std::chrono;
static SingletonPtr<Timer> timer;
static SingletonPtr<Timeout> timeout; static SingletonPtr<Timeout> timeout;
// If critical sections are implemented using mutexes, timers must be called in thread context, and // If critical sections are implemented using mutexes, timers must be called in thread context, and
@ -42,8 +43,11 @@ static SingletonPtr<Timeout> timeout;
#if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT #if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
static EventQueue *equeue; static EventQueue *equeue;
#endif #endif
namespace {
static uint32_t due; using slot_period = std::ratio_multiply<ratio<50>, micro>;
using slots_t = duration<uint32_t, slot_period>;
}
static HighResClock::time_point due;
static void (*arm_hal_callback)(void); static void (*arm_hal_callback)(void);
#if defined(NS_EVENTLOOP_USE_TICK_TIMER) #if defined(NS_EVENTLOOP_USE_TICK_TIMER)
@ -69,14 +73,15 @@ int8_t platform_tick_timer_register(void (*tick_timer_cb_handler)(void))
int8_t platform_tick_timer_start(uint32_t period_ms) int8_t platform_tick_timer_start(uint32_t period_ms)
{ {
int8_t retval = -1; int8_t retval = -1;
auto period = duration<uint32_t, milli>(period_ms);
if (tick_timer_cb && tick_timer_id == 0) { if (tick_timer_cb && tick_timer_id == 0) {
#if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT #if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
tick_timer_id = equeue->call_every(period_ms, tick_timer_cb); tick_timer_id = equeue->call_every(period, tick_timer_cb);
if (tick_timer_id != 0) { if (tick_timer_id != 0) {
retval = 0; retval = 0;
} }
#else #else
tick_ticker->attach_us(tick_timer_cb, period_ms * 1000); tick_ticker->attach(tick_timer_cb, period);
tick_timer_id = 1; tick_timer_id = 1;
retval = 0; retval = 0;
#endif #endif
@ -108,7 +113,6 @@ void platform_timer_enable(void)
equeue = mbed_highprio_event_queue(); equeue = mbed_highprio_event_queue();
MBED_ASSERT(equeue != NULL); MBED_ASSERT(equeue != NULL);
#endif #endif
timer->start();
// Prime the SingletonPtr - can't construct from IRQ/critical section // Prime the SingletonPtr - can't construct from IRQ/critical section
timeout.get(); timeout.get();
} }
@ -127,7 +131,7 @@ void platform_timer_set_cb(void (*new_fp)(void))
static void timer_callback(void) static void timer_callback(void)
{ {
due = 0; due = HighResClock::time_point{};
#if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT #if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
// Callback is interrupt safe so it can be called directly without // Callback is interrupt safe so it can be called directly without
@ -141,17 +145,17 @@ static void timer_callback(void)
// This is called from inside platform_enter_critical - IRQs can't happen // This is called from inside platform_enter_critical - IRQs can't happen
void platform_timer_start(uint16_t slots) void platform_timer_start(uint16_t slots)
{ {
timer->reset(); slots_t rel_time{slots};
due = slots * UINT32_C(50); due = HighResClock::now() + rel_time;
timeout->attach_us(timer_callback, due); timeout->attach_absolute(timer_callback, due);
} }
// This is called from inside platform_enter_critical - IRQs can't happen // This is called from inside platform_enter_critical - IRQs can't happen
uint16_t platform_timer_get_remaining_slots(void) uint16_t platform_timer_get_remaining_slots(void)
{ {
uint32_t elapsed = timer->read_us(); auto now = HighResClock::now();
if (elapsed < due) { if (now < due) {
return (uint16_t)((due - elapsed) / 50); return duration_cast<slots_t>(due - now).count();
} else { } else {
return 0; return 0;
} }