Skip to content

Commit

Permalink
tests/sys_irq_handler: test for sys/irq_handler
Browse files Browse the repository at this point in the history
Test application for sys/irq_handler.
  • Loading branch information
gschorcht committed Aug 13, 2019
1 parent 82e020f commit 5fe75a9
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 0 deletions.
11 changes: 11 additions & 0 deletions tests/sys_irq_handler/Makefile
@@ -0,0 +1,11 @@
include ../Makefile.tests_common

BOARD_INSUFFICIENT_MEMORY := arduino-duemilanove arduino-nano \
arduino-uno nucleo-f031k6

CFLAGS += -DIRQ_HANDLER_PRIO=THREAD_PRIORITY_MAIN+1

USEMODULE += irq_handler
USEMODULE += xtimer

include $(RIOTBASE)/Makefile.include
170 changes: 170 additions & 0 deletions tests/sys_irq_handler/main.c
@@ -0,0 +1,170 @@
/*
* Copyright (C) 2019 Gunar Schorcht
*
* 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 Interrupt handler test application
*
* @author Gunar Schorcht <gunar@schorcht.net>
*
* This application demonstrates how to use the interrupt handler thread
* module `irq_handler`. For that purpose the main thread simulates interrupts
* from 2 interrupt sources with different priorities with a period
* of a half second. One interrupt source triggeres a second interrupt before
* the interrupts can be handled by the interrupt handler.
*
* To be able to simulate the interrupts by the main thread, the interrupt
* handler thread has to have a lower priority as the main thread for this
* example. Otherwise, the interrupts would be handled immediatly when they
* are generated by the main thread. Therefore the interrupt handler thread
* priority is set to THREAD_PRIORITY_MAIN+1 for this example.
* @}
*/

#include <errno.h>
#include <stdio.h>

#include "irq_handler.h"
#include "mutex.h"
#include "thread.h"
#include "xtimer.h"

#define TEST_TIME (100 * US_PER_MS)
#define TEST_REPETITIONS (10)

static void _int1_service (void *arg);
static void _int2_service (void *arg);

static char some_stack[THREAD_STACKSIZE_MAIN];
static int i = 0;
static int n_int1_handled = 0;
static int n_int2_handled = 0;
static int n_already_pending = 0;
static mutex_t mutex = MUTEX_INIT;
xtimer_t timer1a = {
.callback = _int1_service,
.arg = &timer1a
};
xtimer_t timer1b = {
.callback = _int1_service,
.arg = &timer1b
};
xtimer_t timer2 = {
.callback = _int2_service,
.arg = &timer2
};

/* preallocated and initialized interrupt event objects */
static irq_event_t _int1_event = IRQ_EVENT_INIT;
static irq_event_t _int2_event = IRQ_EVENT_INIT;

/* interrupt service routine for a simulated interrupt from source 1 */
static void _int1_service (void *arg)
{
(void)arg;
puts("int1 triggered");
/* registers just the interrupt event and returns */
if (irq_event_add(&_int1_event) == -EALREADY) {
puts("int1 is already pending");
n_already_pending++;
}
}

/* interrupt handler for interrupts from source 1 */
static void _int1_handler(void *ctx)
{
xtimer_t *timer = ctx;
xtimer_set(timer, TEST_TIME);
puts("int1 handled");
mutex_lock(&mutex);
n_int1_handled++;
mutex_unlock(&mutex);
}

/* interrupt service routine for a simulated interrupt from source 2 */
static void _int2_service (void *arg)
{
(void)arg;
puts("int2 triggered");
/* registers just the interrupt event and returns */
if (irq_event_add(&_int2_event) == -EALREADY) {
puts("int2 is already pending");
n_already_pending++;
}
}

/* interrupt handler for interrupts from source 2 */
static void _int2_handler(void *ctx)
{
xtimer_t *timer = ctx;
xtimer_set(timer, TEST_TIME);
puts("int2 handled");
mutex_lock(&mutex);
n_int2_handled++;
mutex_unlock(&mutex);
}

static void *some_thread(void *arg)
{
(void)arg;

puts("some_thread is starting");

while (1) {
mutex_lock(&mutex);
i++;
mutex_unlock(&mutex);
xtimer_usleep(US_PER_MS);
}
return NULL;
}

int main(void)
{
_int1_event.isr = _int1_handler;
_int1_event.ctx = &timer1a;

_int2_event.isr = _int2_handler;
_int2_event.ctx = &timer2;

puts("START");

thread_create(some_stack, sizeof(some_stack),
THREAD_PRIORITY_MAIN + 2, THREAD_CREATE_WOUT_YIELD,
some_thread, NULL, "some_thread");
puts("some_thread created");

/* wait to let some_thread to start */
xtimer_usleep(US_PER_SEC);

i = 0;

xtimer_set(&timer1a, TEST_TIME);
xtimer_set(&timer1b, TEST_TIME);
xtimer_set(&timer2, TEST_TIME);

xtimer_usleep(TEST_TIME * TEST_REPETITIONS + TEST_TIME/2);

xtimer_remove(&timer1a);
xtimer_remove(&timer1b);
xtimer_remove(&timer2);

mutex_lock(&mutex);
if ((i > 0) &&
(n_int1_handled == TEST_REPETITIONS) &&
(n_int2_handled == TEST_REPETITIONS) &&
(n_already_pending == 1)) {
puts("[SUCCESS]");
}
mutex_unlock(&mutex);

return 0;
}

0 comments on commit 5fe75a9

Please sign in to comment.