mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #6000 from kaspar030/add_event_system
sys: add asynchronous event system
This commit is contained in:
commit
0954dba17d
12
Makefile.dep
12
Makefile.dep
@ -679,6 +679,18 @@ ifneq (,$(filter sock_dns,$(USEMODULE)))
|
||||
USEMODULE += sock_util
|
||||
endif
|
||||
|
||||
ifneq (,$(filter event_%,$(USEMODULE)))
|
||||
USEMODULE += event
|
||||
endif
|
||||
|
||||
ifneq (,$(filter event_timeout,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter event,$(USEMODULE)))
|
||||
USEMODULE += core_thread_flags
|
||||
endif
|
||||
|
||||
ifneq (,$(filter spiffs,$(USEMODULE)))
|
||||
USEPKG += spiffs
|
||||
USEMODULE += vfs
|
||||
|
@ -8,6 +8,7 @@ PSEUDOMODULES += cbor_semantic_tagging
|
||||
PSEUDOMODULES += conn_can_isotp_multi
|
||||
PSEUDOMODULES += core_%
|
||||
PSEUDOMODULES += emb6_router
|
||||
PSEUDOMODULES += event_%
|
||||
PSEUDOMODULES += gnrc_ipv6_default
|
||||
PSEUDOMODULES += gnrc_ipv6_router
|
||||
PSEUDOMODULES += gnrc_ipv6_router_default
|
||||
|
5
sys/event/Makefile
Normal file
5
sys/event/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
SRC := event.c
|
||||
|
||||
SUBMODULES = 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
22
sys/event/callback.c
Normal file
22
sys/event/callback.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.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.
|
||||
*/
|
||||
|
||||
#include "event/callback.h"
|
||||
|
||||
void _event_callback_handler(event_t *event)
|
||||
{
|
||||
event_callback_t *event_callback = (event_callback_t *) event;
|
||||
event_callback->callback(event_callback->arg);
|
||||
}
|
||||
|
||||
void event_callback_init(event_callback_t *event_callback, void (callback)(void *), void *arg)
|
||||
{
|
||||
event_callback->super.handler = _event_callback_handler;
|
||||
event_callback->callback = callback;
|
||||
event_callback->arg = arg;
|
||||
}
|
79
sys/event/event.c
Normal file
79
sys/event/event.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "event.h"
|
||||
#include "clist.h"
|
||||
#include "thread.h"
|
||||
|
||||
void event_queue_init(event_queue_t *queue)
|
||||
{
|
||||
assert(queue);
|
||||
memset(queue, '\0', sizeof(*queue));
|
||||
queue->waiter = (thread_t *)sched_active_thread;
|
||||
}
|
||||
|
||||
void event_post(event_queue_t *queue, event_t *event)
|
||||
{
|
||||
assert(!event->list_node.next);
|
||||
assert(queue->waiter);
|
||||
|
||||
unsigned state = irq_disable();
|
||||
clist_rpush(&queue->event_list, &event->list_node);
|
||||
irq_restore(state);
|
||||
|
||||
thread_flags_set(queue->waiter, THREAD_FLAG_EVENT);
|
||||
}
|
||||
|
||||
void event_cancel(event_queue_t *queue, event_t *event)
|
||||
{
|
||||
assert(queue);
|
||||
assert(event);
|
||||
|
||||
unsigned state = irq_disable();
|
||||
clist_remove(&queue->event_list, &event->list_node);
|
||||
event->list_node.next = NULL;
|
||||
irq_restore(state);
|
||||
}
|
||||
|
||||
event_t *event_get(event_queue_t *queue)
|
||||
{
|
||||
unsigned state = irq_disable();
|
||||
event_t *result = (event_t *) clist_lpop(&queue->event_list);
|
||||
|
||||
irq_restore(state);
|
||||
if (result) {
|
||||
result->list_node.next = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
event_t *event_wait(event_queue_t *queue)
|
||||
{
|
||||
thread_flags_wait_any(THREAD_FLAG_EVENT);
|
||||
unsigned state = irq_disable();
|
||||
event_t *result = (event_t *) clist_lpop(&queue->event_list);
|
||||
if (clist_rpeek(&queue->event_list)) {
|
||||
queue->waiter->flags |= THREAD_FLAG_EVENT;
|
||||
}
|
||||
irq_restore(state);
|
||||
result->list_node.next = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
void event_loop(event_queue_t *queue)
|
||||
{
|
||||
event_t *event;
|
||||
|
||||
while ((event = event_wait(queue))) {
|
||||
event->handler(event);
|
||||
}
|
||||
}
|
28
sys/event/timeout.c
Normal file
28
sys/event/timeout.c
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.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.
|
||||
*/
|
||||
|
||||
#include "event/timeout.h"
|
||||
|
||||
static void _event_timeout_callback(void *arg)
|
||||
{
|
||||
event_timeout_t *event_timeout = (event_timeout_t *)arg;
|
||||
event_post(event_timeout->queue, event_timeout->event);
|
||||
}
|
||||
|
||||
void event_timeout_init(event_timeout_t *event_timeout, event_queue_t *queue, event_t *event)
|
||||
{
|
||||
event_timeout->timer.callback = _event_timeout_callback;
|
||||
event_timeout->timer.arg = event_timeout;
|
||||
event_timeout->queue = queue;
|
||||
event_timeout->event = event;
|
||||
}
|
||||
|
||||
void event_timeout_set(event_timeout_t *event_timeout, uint32_t timeout)
|
||||
{
|
||||
xtimer_set(&event_timeout->timer, timeout);
|
||||
}
|
218
sys/include/event.h
Normal file
218
sys/include/event.h
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup sys_event Event Queue
|
||||
* @ingroup sys
|
||||
* @brief Provides an Event loop
|
||||
*
|
||||
* This module offers an event queue framework like libevent or libuev.
|
||||
*
|
||||
* An event queue is basically a FIFO queue of events, with some functions to
|
||||
* efficiently and safely handle adding and getting events to / from such a
|
||||
* queue.
|
||||
* An event queue is bound to a thread, but any thread or ISR can put events
|
||||
* into a queue.
|
||||
*
|
||||
* An event is a structure containing a pointer to an event handler. It can be
|
||||
* extended to provide context or arguments to the handler. It can also be
|
||||
* embedded into existing structures (see examples).
|
||||
*
|
||||
* Compared to msg or mbox, this some fundamental differences:
|
||||
*
|
||||
* 1. events are "sender allocated". Unlike msg_send(), event_post() never
|
||||
* blocks or fails.
|
||||
* 2. events contain everything necessary to handle them, thus a thread
|
||||
* processing the events of an event queue doesn't need to be changed in
|
||||
* order to support new event types.
|
||||
* 3. events can be safely used (and actually perform best) when used within
|
||||
* one thread, e.g., in order to create a state-machine like process flow.
|
||||
* This is not (easily) possible using msg queues, as they might fill up.
|
||||
* 4. an event can only be queued in one event queue at the same time.
|
||||
* Notifying many queues using only one event object is not possible with
|
||||
* this imlementation.
|
||||
*
|
||||
* At the core, event_wait() uses thread flags to implement waiting for events
|
||||
* to be queued. Thus event queues can be used safely and efficiently in combination
|
||||
* with thread flags and msg queues.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
|
||||
* // simple event handler
|
||||
* static void handler(event_t *event)
|
||||
* {
|
||||
* printf("triggered 0x%08x\n", (unsigned)event);
|
||||
* }
|
||||
*
|
||||
* static event_t event = { .handler = handler };
|
||||
* static event_queue_t queue;
|
||||
*
|
||||
* int main(void)
|
||||
* {
|
||||
* event_queue_init(&queue);
|
||||
* event_loop(&queue);
|
||||
* }
|
||||
*
|
||||
* [...] event_post(&queue, &event);
|
||||
*
|
||||
* // example for event extended event struct
|
||||
* typedef struct {
|
||||
* event_t super;
|
||||
* const char *text;
|
||||
* } custom_event_t;
|
||||
*
|
||||
* static void custom_handler(event_t *event)
|
||||
* {
|
||||
* custom_event_t *custom_event = (custom_event_t *)event;
|
||||
* printf("triggered custom event with text: \"%s\"\n", custom_event->text);
|
||||
* }
|
||||
*
|
||||
* static custom_event_t custom_event = { .super.callback = custom_handler, .text = "CUSTOM EVENT" };
|
||||
*
|
||||
* [...] event_post(&queue, &custom_event)
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Event API
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#ifndef EVENT_H
|
||||
#define EVENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "irq.h"
|
||||
#include "thread_flags.h"
|
||||
#include "clist.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef THREAD_FLAG_EVENT
|
||||
/**
|
||||
* @brief Thread flag use to notify available events in an event queue
|
||||
*/
|
||||
#define THREAD_FLAG_EVENT (0x1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief event_queue_t static initializer
|
||||
*/
|
||||
#define EVENT_QUEUE_INIT { .waiter = (thread_t *)sched_active_thread }
|
||||
|
||||
/**
|
||||
* @brief event structure forward declaration
|
||||
*/
|
||||
typedef struct event event_t;
|
||||
|
||||
/**
|
||||
* @brief event handler type definition
|
||||
*/
|
||||
typedef void (*event_handler_t)(event_t *);
|
||||
|
||||
/**
|
||||
* @brief event structure
|
||||
*/
|
||||
struct event {
|
||||
clist_node_t list_node; /**< event queue list entry */
|
||||
event_handler_t handler; /**< pointer to event handler function */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief event queue structure
|
||||
*/
|
||||
typedef struct {
|
||||
clist_node_t event_list; /**< list of queued events */
|
||||
thread_t *waiter; /**< thread ownning event queue */
|
||||
} event_queue_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize an event queue
|
||||
*
|
||||
* This will set the calling thread as owner of @p queue.
|
||||
*
|
||||
* @param[out] queue event queue object to initialize
|
||||
*/
|
||||
void event_queue_init(event_queue_t *queue);
|
||||
|
||||
/**
|
||||
* @brief Queue an event
|
||||
*
|
||||
* @param[in] queue event queue to queue event in
|
||||
* @param[in] event event to queue in event queue
|
||||
*/
|
||||
void event_post(event_queue_t *queue, event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Cancel a queued event
|
||||
*
|
||||
* This will remove a queued event from an event queue.
|
||||
*
|
||||
* @note Due to the underlying list implementation, this will run in O(n).
|
||||
*
|
||||
* @param[in] queue event queue to remove event from
|
||||
* @param[in] event event to remove from queue
|
||||
*/
|
||||
void event_cancel(event_queue_t *queue, event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Get next event from event queue, non-blocking
|
||||
*
|
||||
* In order to handle an event retrieved using this function,
|
||||
* call event->handler(event).
|
||||
*
|
||||
* @param[in] queue event queue to get event from
|
||||
*
|
||||
* @returns pointer to next event
|
||||
* @returns NULL if no event available
|
||||
*/
|
||||
event_t *event_get(event_queue_t *queue);
|
||||
|
||||
/**
|
||||
* @brief Get next event from event queue, blocking
|
||||
*
|
||||
* This function will block until an event becomes available.
|
||||
*
|
||||
* In order to handle an event retrieved using this function,
|
||||
* call event->handler(event).
|
||||
*
|
||||
* @param[in] queue event queue to get event from
|
||||
*
|
||||
* @returns pointer to next event
|
||||
*/
|
||||
event_t *event_wait(event_queue_t *queue);
|
||||
|
||||
/**
|
||||
* @brief Simple event loop
|
||||
*
|
||||
* This function will forever sit in a loop, waiting for events to be queued
|
||||
* and executing their handlers.
|
||||
*
|
||||
* It is pretty much defined as:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
|
||||
* while ((event = event_wait(queue))) {
|
||||
* event->handler(event);
|
||||
* }
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* @param[in] queue event queue to process
|
||||
*/
|
||||
void event_loop(event_queue_t *queue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* EVENT_H */
|
||||
/** @} */
|
87
sys/include/event/callback.h
Normal file
87
sys/include/event/callback.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.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 sys_event
|
||||
* @brief Provides a callback-with-argument event type
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
|
||||
* void callback(void *arg)
|
||||
* {
|
||||
* printf("%s called with arg %p\n", __func__, arg);
|
||||
* }
|
||||
*
|
||||
* [...]
|
||||
* event_callback_t event_callback = EVENT_CALLBACK_INIT(callback, 0x12345678);
|
||||
* event_post(&queue, &event_callback);
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Event Callback API
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#ifndef EVENT_CALLBACK_H
|
||||
#define EVENT_CALLBACK_H
|
||||
|
||||
#include "event.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Callback Event structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
event_t super; /**< event_t structure that gets extended */
|
||||
void (*callback)(void*); /**< callback function */
|
||||
void *arg; /**< callback function argument */
|
||||
} event_callback_t;
|
||||
|
||||
/**
|
||||
* @brief event callback initialization function
|
||||
*
|
||||
* @param[out] event_callback object to initialize
|
||||
* @param[in] callback callback to set up
|
||||
* @param[in] arg callback argument to set up
|
||||
*/
|
||||
void event_callback_init(event_callback_t *event_callback, void (*callback)(void *), void *arg);
|
||||
|
||||
/**
|
||||
* @brief event callback handler function (used internally)
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param[in] event callback event to process
|
||||
*/
|
||||
void _event_callback_handler(event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Callback Event static initializer
|
||||
*
|
||||
* @param[in] _cb callback function to set
|
||||
* @param[in] _arg arguments to set
|
||||
*/
|
||||
#define EVENT_CALLBACK_INIT(_cb, _arg) \
|
||||
{ \
|
||||
.super.handler = _event_callback_handler, \
|
||||
.callback = _cb, \
|
||||
.arg = (void *)_arg \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* EVENT_CALLBACK_H */
|
||||
/** @} */
|
81
sys/include/event/timeout.h
Normal file
81
sys/include/event/timeout.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.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 sys_event
|
||||
* @brief Provides functionality to trigger events after timeout
|
||||
*
|
||||
* event_timeout intentionally does't extend event structures in order to
|
||||
* support events that are integrated in larger structs intrusively.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
|
||||
* event_timeout_t event_timeout;
|
||||
*
|
||||
* printf("posting timed callback with timeout 1sec\n");
|
||||
* event_timeout_init(&event_timeout, &queue, (event_t*)&event);
|
||||
* event_timeout_set(&event_timeout, 1000000);
|
||||
* [...]
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Event Timeout API
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#ifndef EVENT_TIMEOUT_H
|
||||
#define EVENT_TIMEOUT_H
|
||||
|
||||
#include "event.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Timeout Event structure
|
||||
*/
|
||||
typedef struct {
|
||||
xtimer_t timer; /**< xtimer object used for timeout */
|
||||
event_queue_t *queue; /**< event queue to post event to */
|
||||
event_t *event; /**< event to post after timeout */
|
||||
} event_timeout_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize timeout event object
|
||||
*
|
||||
* @param[in] event_timeout event_timeout object to initilalize
|
||||
* @param[in] queue queue that the timed-out event will be added to
|
||||
* @param[in] event event to add to queue after timeout
|
||||
*/
|
||||
void event_timeout_init(event_timeout_t *event_timeout, event_queue_t *queue, event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Set a timeout
|
||||
*
|
||||
* This will make the event as configured in @p event_timeout be triggered
|
||||
* after @p timeout miliseconds.
|
||||
*
|
||||
* @note: the used event_timeout struct must stay valid until after the timeout
|
||||
* event has been processed!
|
||||
*
|
||||
* @param[in] event_timeout event_timout context onject to use
|
||||
* @param[in] timeout timeout in miliseconds
|
||||
*/
|
||||
void event_timeout_set(event_timeout_t *event_timeout, uint32_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* EVENT_TIMEOUT_H */
|
||||
/** @} */
|
11
tests/events/Makefile
Normal file
11
tests/events/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
APPLICATION = event
|
||||
include ../Makefile.tests_common
|
||||
|
||||
FORCE_ASSERTS = 1
|
||||
USEMODULE += event_callback
|
||||
USEMODULE += event_timeout
|
||||
|
||||
test:
|
||||
tests/01-run.py
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
102
tests/events/main.c
Normal file
102
tests/events/main.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.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 event test application
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "thread.h"
|
||||
#include "event.h"
|
||||
#include "event/timeout.h"
|
||||
#include "event/callback.h"
|
||||
|
||||
static unsigned order;
|
||||
static uint32_t before;
|
||||
|
||||
static void callback(event_t *arg);
|
||||
static void custom_callback(event_t *event);
|
||||
static void timed_callback(void *arg);
|
||||
|
||||
|
||||
static event_t event = { .handler = callback };
|
||||
static event_t event2 = { .handler = callback };
|
||||
|
||||
static void callback(event_t *arg)
|
||||
{
|
||||
order++;
|
||||
assert(order == 1);
|
||||
assert(arg == &event);
|
||||
printf("triggered 0x%08x\n", (unsigned)arg);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
event_t super;
|
||||
const char *text;
|
||||
} custom_event_t;
|
||||
|
||||
static custom_event_t custom_event = { .super.handler = custom_callback, .text = "CUSTOM CALLBACK" };
|
||||
static event_callback_t event_callback = EVENT_CALLBACK_INIT(timed_callback, 0x12345678);
|
||||
|
||||
static void custom_callback(event_t *event)
|
||||
{
|
||||
order++;
|
||||
assert(order == 2);
|
||||
assert(event == (event_t *)&custom_event);
|
||||
custom_event_t *custom_event = (custom_event_t *)event;
|
||||
printf("triggered custom event with text: \"%s\"\n", custom_event->text);
|
||||
}
|
||||
|
||||
static void timed_callback(void *arg)
|
||||
{
|
||||
order++;
|
||||
assert(order == 3);
|
||||
assert(arg == event_callback.arg);
|
||||
uint32_t now = xtimer_now_usec();
|
||||
assert((now - before >= 100000LU));
|
||||
printf("triggered timed callback with arg 0x%08x after %" PRIu32 "us\n", (unsigned)arg, now - before);
|
||||
printf("[SUCCESS]\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("[START] event test application.\n");
|
||||
|
||||
event_queue_t queue = { .waiter = (thread_t *)sched_active_thread };
|
||||
printf("posting 0x%08x\n", (unsigned)&event);
|
||||
event_post(&queue, &event);
|
||||
|
||||
printf("posting 0x%08x\n", (unsigned)&event2);
|
||||
event_post(&queue, &event2);
|
||||
printf("canceling 0x%08x\n", (unsigned)&event2);
|
||||
event_cancel(&queue, &event2);
|
||||
|
||||
printf("posting custom event\n");
|
||||
event_post(&queue, (event_t *)&custom_event);
|
||||
|
||||
event_timeout_t event_timeout;
|
||||
|
||||
printf("posting timed callback with timeout 1sec\n");
|
||||
event_timeout_init(&event_timeout, &queue, (event_t *)&event_callback);
|
||||
before = xtimer_now_usec();
|
||||
event_timeout_set(&event_timeout, 100000LU);
|
||||
|
||||
printf("launching event queue\n");
|
||||
event_loop(&queue);
|
||||
|
||||
return 0;
|
||||
}
|
20
tests/events/tests/01-run.py
Executable file
20
tests/events/tests/01-run.py
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
# 2017 Sebastian Meiling <s@mlng.net>
|
||||
#
|
||||
# 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 os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
|
||||
import testrunner
|
||||
|
||||
def testfunc(child):
|
||||
child.expect_exact(u"[SUCCESS]")
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(testrunner.run(testfunc))
|
Loading…
Reference in New Issue
Block a user