Nanostack HAL: Convert to Chrono

pull/12903/head
Kevin Bracey 2020-03-03 16:52:51 +02:00
parent d1ae0d570c
commit c037d50e1b
2 changed files with 43 additions and 43 deletions

View File

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

View File

@ -23,15 +23,16 @@
#include "platform/arm_hal_interrupt.h"
#include "platform/mbed_assert.h"
#include "Timeout.h"
#include "Timer.h"
#include "Ticker.h"
#include "events/Event.h"
#include "events/mbed_shared_queues.h"
using namespace mbed;
using namespace events;
using std::ratio;
using std::milli;
using std::micro;
using namespace std::chrono;
static SingletonPtr<Timer> timer;
static SingletonPtr<Timeout> timeout;
// 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
static EventQueue *equeue;
#endif
static uint32_t due;
namespace {
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);
#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 retval = -1;
auto period = duration<uint32_t, milli>(period_ms);
if (tick_timer_cb && tick_timer_id == 0) {
#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) {
retval = 0;
}
#else
tick_ticker->attach_us(tick_timer_cb, period_ms * 1000);
tick_ticker->attach(tick_timer_cb, period);
tick_timer_id = 1;
retval = 0;
#endif
@ -108,7 +113,6 @@ void platform_timer_enable(void)
equeue = mbed_highprio_event_queue();
MBED_ASSERT(equeue != NULL);
#endif
timer->start();
// Prime the SingletonPtr - can't construct from IRQ/critical section
timeout.get();
}
@ -127,7 +131,7 @@ void platform_timer_set_cb(void (*new_fp)(void))
static void timer_callback(void)
{
due = 0;
due = HighResClock::time_point{};
#if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
// 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
void platform_timer_start(uint16_t slots)
{
timer->reset();
due = slots * UINT32_C(50);
timeout->attach_us(timer_callback, due);
slots_t rel_time{slots};
due = HighResClock::now() + rel_time;
timeout->attach_absolute(timer_callback, due);
}
// This is called from inside platform_enter_critical - IRQs can't happen
uint16_t platform_timer_get_remaining_slots(void)
{
uint32_t elapsed = timer->read_us();
if (elapsed < due) {
return (uint16_t)((due - elapsed) / 50);
auto now = HighResClock::now();
if (now < due) {
return duration_cast<slots_t>(due - now).count();
} else {
return 0;
}