npl/riot: rework to use RIOTs ztimer

ztimer is a new high-level timer API in RIOT that was introcuced a
while ago to be the successor of xtimer. This commit reworks the
RIOT NPL implementation to use ztimer instead of xtimer. This
simplifies the NPL implementation and it allows for significant
energy savings.
For the xtimer switch the implemenation further switches from
RIOTs `posix_semaphore` module to the slimmer `sema` module, as the
prior indirectly pulls in xtimer as dependency.
This commit is contained in:
Hauke Petersen
2021-04-15 11:25:05 +02:00
committed by Hauke Petersen
parent 1d073cc84d
commit 940cc0b4a8
2 changed files with 26 additions and 46 deletions
+18 -27
View File
@@ -24,8 +24,8 @@
#include <stdbool.h>
#include "event/callback.h"
#include "mutex.h"
#include "semaphore.h"
#include "xtimer.h"
#include "sema.h"
#include "ztimer.h"
#ifdef __cplusplus
extern "C" {
@@ -50,8 +50,8 @@ struct ble_npl_eventq {
};
struct ble_npl_callout {
xtimer_t timer;
uint64_t target_us;
ztimer_t timer;
ble_npl_time_t ticks;
struct ble_npl_event e;
event_queue_t *q;
};
@@ -61,7 +61,7 @@ struct ble_npl_mutex {
};
struct ble_npl_sem {
sem_t sem;
sema_t sem;
};
static inline bool
@@ -100,8 +100,9 @@ ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo)
} else if (tmo == BLE_NPL_TIME_FOREVER) {
return (struct ble_npl_event *)event_wait(&evq->q);
} else {
return (struct ble_npl_event *)event_wait_timeout64(&evq->q,
tmo * US_PER_MS);
return (struct ble_npl_event *)event_wait_timeout_ztimer(&evq->q,
ZTIMER_MSEC,
(uint32_t)tmo);
}
}
@@ -174,49 +175,39 @@ ble_npl_mutex_release(struct ble_npl_mutex *mu)
static inline ble_npl_error_t
ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
{
int rc;
rc = sem_init(&sem->sem, 0, tokens);
return rc == 0 ? BLE_NPL_OK : BLE_NPL_ERROR;
sema_create(&sem->sem, (unsigned)tokens);
return BLE_NPL_OK;
}
static inline ble_npl_error_t
ble_npl_sem_release(struct ble_npl_sem *sem)
{
int rc;
rc = sem_post(&sem->sem);
return rc == 0 ? BLE_NPL_OK : BLE_NPL_ERROR;
int rc = sema_post(&sem->sem);
return (rc == 0) ? BLE_NPL_OK : BLE_NPL_ERROR;
}
static inline uint16_t
ble_npl_sem_get_count(struct ble_npl_sem *sem)
{
int val = 0;
sem_getvalue(&sem->sem, &val);
return (uint16_t)val;
return (uint16_t)sema_get_value(&sem->sem);
}
static inline void
ble_npl_callout_stop(struct ble_npl_callout *co)
{
xtimer_remove(&co->timer);
ztimer_remove(ZTIMER_MSEC, &co->timer);
}
static inline bool
ble_npl_callout_is_active(struct ble_npl_callout *c)
{
return (c->timer.offset || c->timer.long_offset);
return ztimer_is_set(ZTIMER_MSEC, &c->timer);
}
static inline ble_npl_time_t
ble_npl_callout_get_ticks(struct ble_npl_callout *co)
{
return (ble_npl_time_t)(co->target_us / US_PER_MS);
return co->ticks;
}
static inline void
@@ -228,7 +219,7 @@ ble_npl_callout_set_arg(struct ble_npl_callout *co, void *arg)
static inline ble_npl_time_t
ble_npl_time_get(void)
{
return (ble_npl_time_t)(xtimer_now_usec64() / US_PER_MS);
return (ble_npl_time_t)ztimer_now(ZTIMER_MSEC);
}
static inline ble_npl_error_t
@@ -260,7 +251,7 @@ ble_npl_time_ticks_to_ms32(ble_npl_time_t ticks)
static inline void
ble_npl_time_delay(ble_npl_time_t ticks)
{
xtimer_usleep64(ticks * US_PER_MS);
ztimer_sleep(ZTIMER_MSEC, (uint32_t)ticks);
}
static inline uint32_t
+8 -19
View File
@@ -35,18 +35,8 @@ _callout_fire(void *arg)
ble_npl_error_t
ble_npl_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout)
{
int rc;
struct timespec abs;
uint64_t time;
time = xtimer_now_usec64() +
(ble_npl_time_ticks_to_ms32(timeout) * US_PER_MS);
abs.tv_sec = (time_t)(time / US_PER_SEC);
abs.tv_nsec = (long)((time % US_PER_SEC) * NS_PER_US);
rc = sem_timedwait(&sem->sem, &abs);
return rc == 0 ? BLE_NPL_OK : BLE_NPL_ENOENT;
int rc = sema_wait_timed_ztimer(&sem->sem, ZTIMER_MSEC, timeout);
return (rc == 0) ? BLE_NPL_OK : BLE_NPL_ENOENT;
}
void
@@ -62,19 +52,18 @@ ble_npl_callout_init(struct ble_npl_callout *c, struct ble_npl_eventq *evq,
ble_npl_error_t
ble_npl_callout_reset(struct ble_npl_callout *c, ble_npl_time_t ticks)
{
/* Use critical section to ensure matching target_us and xtimer value. */
/* Use critical section to ensure matching target_us and ztimer value. */
uint32_t crit_state = ble_npl_hw_enter_critical();
uint64_t now = xtimer_now_usec64();
c->target_us = now + ticks * US_PER_MS;
xtimer_set64(&c->timer, ticks * US_PER_MS);
c->ticks = ztimer_now(ZTIMER_MSEC) + ticks;
ztimer_set(ZTIMER_MSEC, &c->timer, ticks);
ble_npl_hw_exit_critical(crit_state);
return BLE_NPL_OK;
}
uint32_t
ble_npl_time_t
ble_npl_callout_remaining_ticks(struct ble_npl_callout *co,
ble_npl_time_t time)
{
uint64_t now = xtimer_now_usec64();
return (uint32_t)((co->target_us - now) / US_PER_MS);
ztimer_now_t now = ztimer_now(ZTIMER_MSEC);
return (ble_npl_time_t)(co->ticks - now);
}