Skip to content
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

sys/event: add API to start periodic event without initial delay #20911

Merged
merged 3 commits into from
Oct 16, 2024
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
1 change: 0 additions & 1 deletion sys/event/periodic.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
static bool _event_periodic_callback(void *arg)
{
event_periodic_t *event_periodic = (event_periodic_t *)arg;

event_post(event_periodic->queue, event_periodic->event);

if (event_periodic->count && --event_periodic->count == 0) {
Expand Down
22 changes: 22 additions & 0 deletions sys/include/event/periodic.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,28 @@ typedef struct {
void event_periodic_init(event_periodic_t *event_periodic, ztimer_clock_t *clock,
event_queue_t *queue, event_t *event);

/**
* @brief Starts a periodic timeout without delay for the first occurrence
*
* This will make the event as configured in @p event_periodic be triggered
* at every interval ticks (based on event_periodic->clock).
*
* @note: the used event_periodic struct must stay valid until after the timeout
* event has been processed!
*
* @note: this function does not touch the current count value.
*
* @note: the periodic event will start without delay.
*
* @param[in] event_periodic event_timout context object to use
* @param[in] interval period length for the event
*/
static inline void event_periodic_start_now(event_periodic_t *event_periodic, uint32_t interval)
{
event_periodic->timer.interval = interval;
ztimer_periodic_start_now(&event_periodic->timer);
}

/**
* @brief Starts a periodic timeout
*
Expand Down
13 changes: 13 additions & 0 deletions sys/include/ztimer/periodic.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,19 @@ void ztimer_periodic_init(ztimer_clock_t *clock, ztimer_periodic_t *timer,
*/
void ztimer_periodic_start(ztimer_periodic_t *timer);

/**
* @brief Start or restart a periodic timer without initial timer delay
*
* When called on a newly initialized timer, the timer will start.
*
* When called on an already running timer, the current interval is reset to its
* start (thus the next callback will be called after the configured interval
* has passed).
*
* @param[in] timer periodic timer object to work on
*/
void ztimer_periodic_start_now(ztimer_periodic_t *timer);

/**
* @brief Stop a periodic timer
*
Expand Down
5 changes: 5 additions & 0 deletions sys/ztimer/periodic.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ void ztimer_periodic_start(ztimer_periodic_t *timer)
timer->last = ztimer_set(timer->clock, &timer->timer, timer->interval) + timer->interval;
}

void ztimer_periodic_start_now(ztimer_periodic_t *timer)
{
timer->last = ztimer_set(timer->clock, &timer->timer, 0);
}

void ztimer_periodic_stop(ztimer_periodic_t *timer)
{
ztimer_remove(timer->clock, &timer->timer);
Expand Down
12 changes: 9 additions & 3 deletions tests/sys/event_ztimer/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,9 @@ static void callback_4times(void *arg)
uint8_t *count = (uint8_t *)arg;

*count = *count + 1;
uint32_t now = event_periodic.timer.last;
uint32_t now = ztimer_now(ZTIMER_USEC);
uint32_t elapsed = now - before;
before = now;
expect((elapsed) >= 1 * US_PER_SEC);
if (*count <= 4) {
printf("trigger %d of periodic timeout, elapsed time: %" PRIu32 " us\n",
*count, elapsed);
Expand Down Expand Up @@ -110,8 +109,15 @@ int main(void)
event_periodic_init(&event_periodic, ZTIMER_USEC, EVENT_PRIO_MEDIUM,
&event_4times.super);
event_periodic_set_count(&event_periodic, 4);
before = ztimer_now(ZTIMER_USEC);
event_periodic_start(&event_periodic, EVENT_TIMEOUT_TIME);
before = event_periodic.timer.last;
puts("waiting for periodic callback to be triggered 4 times");
mutex_lock(&lock);
puts("posting periodic timed callback with timeout 1sec and no delay");
event_periodic_set_count(&event_periodic, 4);
iter = 0; /* reset callback argument counter to 0 */
before = ztimer_now(ZTIMER_USEC);
event_periodic_start_now(&event_periodic, EVENT_TIMEOUT_TIME);
puts("waiting for periodic callback to be triggered 4 times");
mutex_lock(&lock);
puts("posting timed callback with timeout 0.5sec, clear right after");
Expand Down
Loading