-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14011 from maribu/tests_irq_disable_restore
tests: Add test for irq_disable() / irq_restore()
- Loading branch information
Showing
4 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
include ../Makefile.tests_common | ||
|
||
USEMODULE += fmt | ||
USEMODULE += xtimer | ||
|
||
include $(RIOTBASE)/Makefile.include |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)) |