evtimer: add mbox support

This commit is contained in:
Simon Brummer 2020-07-05 18:13:19 +02:00
parent 0b50187732
commit 5d67daebb2
6 changed files with 207 additions and 0 deletions

View File

@ -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

View File

@ -20,6 +20,7 @@ PSEUDOMODULES += devfs_%
PSEUDOMODULES += dhcpv6_%
PSEUDOMODULES += ecc_%
PSEUDOMODULES += event_%
PSEUDOMODULES += evtimer_mbox
PSEUDOMODULES += fmt_%
PSEUDOMODULES += gnrc_dhcpv6_%
PSEUDOMODULES += gnrc_ipv6_default

View File

@ -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 */
/** @} */

View File

@ -0,0 +1,5 @@
include ../Makefile.tests_common
USEMODULE += evtimer_mbox
include $(RIOTBASE)/Makefile.include

87
tests/evtimer_mbox/main.c Normal file
View File

@ -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");
}
}

View File

@ -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))