mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
tests: Add test for irq_disable() / irq_restore()
This commit is contained in:
parent
8a3d226f35
commit
51c19d5b6b
6
tests/irq_disable_restore/Makefile
Normal file
6
tests/irq_disable_restore/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += fmt
|
||||
USEMODULE += xtimer
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
13
tests/irq_disable_restore/README.md
Normal file
13
tests/irq_disable_restore/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Test for `irq_disable()` and `irq_restore()`
|
||||
|
||||
This test checks if `irq_disable()` and `irq_restore()` work as intended. For
|
||||
that, the test uses two variables *a* and *b*, both initialized with 0. The main
|
||||
test will schedule a timer that expires in *T/2*. It will then set *a* to 1 and
|
||||
waits for *T* until it also sets *b* to one. The expectation is that during the
|
||||
ISR (the timer callback) *a* has a value of 1, but *b* still has a value of 0.
|
||||
|
||||
The test is repeated, but this time the main thread calls `irq_disable()`
|
||||
before setting *a* and `irq_restore()` after setting *b*. It is now expected
|
||||
that - even though the timer again expires after setting *a* and before setting
|
||||
*b* - the execution of the ISR is delayed until `irq_restore()` is called. Thus,
|
||||
both *a* and *b* should already contain the new value in the ISR.
|
99
tests/irq_disable_restore/main.c
Normal file
99
tests/irq_disable_restore/main.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* 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 irq_disable_restore test application
|
||||
*
|
||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fmt.h"
|
||||
#include "irq.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#define DELAY (10 * US_PER_MS)
|
||||
|
||||
static atomic_uint a = ATOMIC_VAR_INIT(0);
|
||||
static atomic_uint a_during_isr = ATOMIC_VAR_INIT(0);
|
||||
static atomic_uint b = ATOMIC_VAR_INIT(0);
|
||||
static atomic_uint b_during_isr = ATOMIC_VAR_INIT(0);
|
||||
|
||||
static void busy_delay(void)
|
||||
{
|
||||
uint32_t start = xtimer_now_usec();
|
||||
while (xtimer_now_usec() - start < DELAY) { }
|
||||
}
|
||||
|
||||
/* Timer callback run in interrupt context; should not trigger between
|
||||
* irq_disable() and irq_restore()
|
||||
*/
|
||||
static void timer_callback(void *unused)
|
||||
{
|
||||
(void)unused;
|
||||
atomic_store(&a_during_isr, atomic_load(&a));
|
||||
atomic_store(&b_during_isr, atomic_load(&b));
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
xtimer_t xt = { .callback = timer_callback };
|
||||
|
||||
print_str("Test for irq_disable() / irq_restore()\n"
|
||||
"======================================\n"
|
||||
"\n");
|
||||
|
||||
print_str("Verifying test works: ");
|
||||
xtimer_set(&xt, DELAY / 2);
|
||||
atomic_store(&a, 1);
|
||||
busy_delay();
|
||||
atomic_store(&b, 1);
|
||||
|
||||
/* Timer should have fired in the middle of busy_delay(), thus value of
|
||||
* a now and during ISR should both be 1, but value of b during ISR should
|
||||
* still be 0 but not it should be 1 */
|
||||
if ((atomic_load(&a) == atomic_load(&a_during_isr)) &&
|
||||
(atomic_load(&b) != atomic_load(&b_during_isr)))
|
||||
{
|
||||
print_str("[SUCCESS]\n");
|
||||
}
|
||||
else {
|
||||
print_str("[FAILURE]\n");
|
||||
}
|
||||
|
||||
print_str("Test result: ");
|
||||
xtimer_set(&xt, DELAY / 2);
|
||||
unsigned state = irq_disable();
|
||||
atomic_store(&a, 2);
|
||||
busy_delay();
|
||||
atomic_store(&b, 2);
|
||||
irq_restore(state);
|
||||
|
||||
/* irq_disable() should have delayed execution of the timer until both
|
||||
* a and b have been set to 2.
|
||||
*/
|
||||
|
||||
if ((atomic_load(&a) == atomic_load(&a_during_isr)) &&
|
||||
(atomic_load(&b) == atomic_load(&b_during_isr)))
|
||||
{
|
||||
print_str("[SUCCESS]\n");
|
||||
}
|
||||
else {
|
||||
print_str("[FAILURE]\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
19
tests/irq_disable_restore/tests/01-run.py
Executable file
19
tests/irq_disable_restore/tests/01-run.py
Executable file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg
|
||||
#
|
||||
# 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_exact("Verifying test works: [SUCCESS]")
|
||||
child.expect_exact("Test result: [SUCCESS]")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run(testfunc))
|
Loading…
Reference in New Issue
Block a user