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

evtimer: add mbox support #14498

Merged
merged 1 commit into from
Aug 21, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,11 @@ ifneq (,$(filter evtimer,$(USEMODULE)))
USEMODULE += xtimer
endif

ifneq (,$(filter evtimer_mbox,$(USEMODULE)))
USEMODULE += evtimer
USEMODULE += core_mbox
endif

ifneq (,$(filter fuzzing,$(USEMODULE)))
USEMODULE += netdev_test
USEMODULE += gnrc_netif
Expand Down
1 change: 1 addition & 0 deletions makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ PSEUDOMODULES += devfs_%
PSEUDOMODULES += dhcpv6_%
PSEUDOMODULES += ecc_%
PSEUDOMODULES += event_%
PSEUDOMODULES += evtimer_mbox
PSEUDOMODULES += fmt_%
PSEUDOMODULES += gnrc_dhcpv6_%
PSEUDOMODULES += gnrc_ipv6_default
Expand Down
91 changes: 91 additions & 0 deletions sys/include/evtimer_mbox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2020 Simon Brummer <simon.brummer@posteo.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @addtogroup sys_evtimer
* @{
*
* @file
* @brief Message box based evtimer event.
*
* @author Simon Brummer <simon.brummer@posteo.de>
*/
#ifndef EVTIMER_MBOX_H
#define EVTIMER_MBOX_H

#include "assert.h"
#include "msg.h"
#include "mbox.h"
#include "evtimer.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Message box event definition.
*/
typedef struct {
evtimer_event_t event; /**< event base class */
msg_t msg; /**< message to store in mbox on event */
mbox_t *mbox; /**< mbox the IPC message shall be stored */
} evtimer_mbox_event_t;

/**
* @brief Adds mbox event to an event timer.
*
* @pre @p evtimer is not NULL.
* @pre @p event is not NULL.
* @pre @p mbox is not NULL.
*
* @param[in] evtimer Timer to add @p event.
* @param[in] event Event to add.
* @param[in] mbox Mbox to store event->msg timer expiration.
*/
static inline void evtimer_add_mbox(evtimer_t *evtimer, evtimer_mbox_event_t *event, mbox_t *mbox)
{
assert(evtimer);
assert(event);
assert(mbox);
event->mbox = mbox;
evtimer_add(evtimer, &(event->event));
}

/**
* @brief Event handler for mbox events.
*
* @pre @p event is not NULL.
*
* @param[in] event The event to handle
*/
static inline void _evtimer_mbox_handler(evtimer_event_t *event)
{
assert(event);
evtimer_mbox_event_t *mbevent = (evtimer_mbox_event_t *)event;
mbox_try_put(mbevent->mbox, &(mbevent->msg));
}

/**
* @brief Initializes event timer for mbox events.
*
* @pre @p evtimer is not NULL.
*
* @param[in] evtimer An event timer
*/
static inline void evtimer_init_mbox(evtimer_t *evtimer)
{
assert(evtimer);
evtimer_init(evtimer, _evtimer_mbox_handler);
}

#ifdef __cplusplus
}
#endif

#endif /* EVTIMER_MBOX_H */
/** @} */
5 changes: 5 additions & 0 deletions tests/evtimer_mbox/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include ../Makefile.tests_common

USEMODULE += evtimer_mbox

include $(RIOTBASE)/Makefile.include
87 changes: 87 additions & 0 deletions tests/evtimer_mbox/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (C) 2020 Simon Brummer <simon.brummer@posteo.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup tests
* @{
*
* @file
* @brief evtimer_mbox test application
*
* @author Simon Brummer <simon.brummer@posteo.de>
*
* @}
*/

#include <stdio.h>

#include "kernel_defines.h"
#include "msg.h"
#include "thread.h"
#include "evtimer_msg.h"
#include "evtimer_mbox.h"

#define MBOX_SIZE (4)
#define TIMEOUT_MS (100)
#define TRIGGER_TIMEOUT_MS (TIMEOUT_MS + TIMEOUT_MS * MBOX_SIZE)

int main(void)
{
/* Initialize mbox and evtimers */
msg_t queue[MBOX_SIZE];
mbox_t mbox;
mbox_init(&mbox, queue, ARRAY_SIZE(queue));

evtimer_t timer;
evtimer_t trigger_timer;
evtimer_init_mbox(&timer);
evtimer_init_msg(&trigger_timer);

/* Initialize mbox events */
evtimer_mbox_event_t events[MBOX_SIZE];

for (unsigned i = 0; i < ARRAY_SIZE(events); ++i) {
evtimer_mbox_event_t *e = events + i;

e->event.offset = TIMEOUT_MS + TIMEOUT_MS * i;
e->msg.type = i;
}

/* Initialize trigger event */
evtimer_msg_event_t trigger;
trigger.event.offset = TRIGGER_TIMEOUT_MS;

/* Add events in reverse order to their expected timeout expiration */
for (int i = ARRAY_SIZE(events) - 1; i >= 0; --i) {
evtimer_add_mbox(&timer, events + i, &mbox);
}
evtimer_add_msg(&trigger_timer, &trigger, thread_getpid());

/* Wait until trigger event expired.*/
msg_t msg;
msg_receive(&msg);

/* Verify mbox content, Expectations are:
* 1) Given mbox is full (always use blocking get)
* 2) All msg.type values are stored in ascending order
*/
int failed = 0;

for (unsigned i = 0; i < MBOX_SIZE; ++i) {
mbox_get(&mbox, &msg);

if (msg.type != i) {
failed = 1;
break;
}
}

if (!failed) {
puts("Test successful\n");
}
}
18 changes: 18 additions & 0 deletions tests/evtimer_mbox/tests/01-run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python3

# Copyright (C) 2020 Simon Brummer <simon.brummer@posteo.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.

import sys
from testrunner import run


def testfunc(child):
child.expect('Test successful')


if __name__ == '__main__':
sys.exit(run(testfunc, timeout=1, echo=True))