Skip to content

Nanostack HAL: Convert to Chrono #12903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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());
}
}
}
}
Expand All @@ -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);
Expand All @@ -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();
Expand Down Expand Up @@ -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,
Expand Down
34 changes: 19 additions & 15 deletions features/nanostack/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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();
}
Expand All @@ -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
Expand All @@ -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;
}
Expand Down