Skip to content

Commit bea4bbc

Browse files
committed
test(test_suite): test unmanaged interrupts
1 parent 919eac0 commit bea4bbc

File tree

3 files changed

+101
-1
lines changed

3 files changed

+101
-1
lines changed

src/constance_port_arm_m_test_driver/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ macro_rules! instantiate_test {
101101
// Most targets should have at least four interrupt lines
102102
const INTERRUPT_LINES: &'static [InterruptNum] = &[16, 17, 18, 19];
103103
const INTERRUPT_PRIORITIES: &'static [InterruptPriority] = &[0x20, 0x60];
104+
105+
#[cfg(feature = "cpu-lock-by-basepri")]
106+
const UNMANAGED_INTERRUPT_PRIORITIES: &'static [InterruptPriority] = &[0x00];
104107
}
105108

106109
static COTTAGE: test_case::App<System> =
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//! Makes sure that CPU Lock doesn't mask unmanaged interrupts.
2+
use constance::{
3+
kernel::{cfg::CfgBuilder, Hunk, InterruptHandler, InterruptLine, Task},
4+
prelude::*,
5+
};
6+
7+
use super::Driver;
8+
use crate::utils::SeqTracker;
9+
10+
pub struct App<System> {
11+
int: Option<InterruptLine<System>>,
12+
seq: Hunk<System, SeqTracker>,
13+
}
14+
15+
impl<System: Kernel> App<System> {
16+
pub const fn new<D: Driver<Self>>(b: &mut CfgBuilder<System>) -> Self {
17+
Task::build()
18+
.start(task_body::<System, D>)
19+
.priority(0)
20+
.active(true)
21+
.finish(b);
22+
23+
let int = if let (&[int_line, ..], &[int_pri, ..]) =
24+
(D::INTERRUPT_LINES, D::UNMANAGED_INTERRUPT_PRIORITIES)
25+
{
26+
unsafe {
27+
InterruptHandler::build()
28+
.line(int_line)
29+
.unmanaged()
30+
.start(isr::<System, D>)
31+
.finish(b);
32+
}
33+
34+
Some(
35+
InterruptLine::build()
36+
.line(int_line)
37+
.priority(int_pri)
38+
.enabled(true)
39+
.finish(b),
40+
)
41+
} else {
42+
None
43+
};
44+
45+
let seq = Hunk::<_, SeqTracker>::build().finish(b);
46+
47+
App { int, seq }
48+
}
49+
}
50+
51+
fn task_body<System: Kernel, D: Driver<App<System>>>(_: usize) {
52+
D::app().seq.expect_and_replace(0, 1);
53+
54+
if let Some(int) = D::app().int {
55+
System::acquire_cpu_lock().unwrap();
56+
D::app().seq.expect_and_replace(1, 2);
57+
int.pend().unwrap();
58+
D::app().seq.expect_and_replace(3, 4);
59+
unsafe { System::release_cpu_lock() }.unwrap();
60+
D::app().seq.expect_and_replace(4, 5);
61+
} else {
62+
log::warn!(
63+
"No interrupt lines and compatible interrupt priorities \
64+
defined, skipping the test"
65+
);
66+
}
67+
68+
D::success();
69+
}
70+
71+
fn isr<System: Kernel, D: Driver<App<System>>>(_: usize) {
72+
D::app().seq.expect_and_replace(2, 3);
73+
}

src/constance_test_suite/src/lib.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub mod kernel_tests {
5151
/// [`pend_interrupt_line`]: constance::kernel::PortInterrupts::pend_interrupt_line
5252
const INTERRUPT_LINES: &'static [InterruptNum] = &[];
5353

54-
/// Valid priority values.
54+
/// Valid managed priority values.
5555
///
5656
/// - The list can have an arbitrary number of elements. Some tests
5757
/// will be silently skipped if it's not enough. There should be at
@@ -66,6 +66,29 @@ pub mod kernel_tests {
6666
///
6767
/// [`MANAGED_INTERRUPT_PRIORITY_RANGE`]: constance::kernel::PortInterrupts::MANAGED_INTERRUPT_PRIORITY_RANGE
6868
const INTERRUPT_PRIORITIES: &'static [InterruptPriority] = &[];
69+
70+
/// Valid unmanaged priority values.
71+
///
72+
/// - The list can have an arbitrary number of elements. Some tests
73+
/// will be silently skipped if it's not enough. There should be at
74+
/// least one for all test cases to run.
75+
///
76+
/// - No elements must be in range
77+
/// [`MANAGED_INTERRUPT_PRIORITY_RANGE`].
78+
///
79+
/// - The elements must be sorted in a descending order of priority.
80+
/// That is, for every pair of adjacent elements `[p[i], p[i + 1]]`,
81+
/// `p[i]` should be high enough to preempt `p[o + 1]`.
82+
///
83+
/// - For every element `pri_unmanaged` in
84+
/// `UNMANAGED_INTERRUPT_PRIORITIES` and every element `pri_managed`
85+
/// in [`INTERRUPT_PRIORITIES`], `pri_unmanaged` should be high
86+
/// enough to preempt `pri_managed`.
87+
///
88+
/// [`MANAGED_INTERRUPT_PRIORITY_RANGE`]: constance::kernel::PortInterrupts::MANAGED_INTERRUPT_PRIORITY_RANGE
89+
/// [`INTERRUPT_PRIORITIES`]: Self::INTERRUPT_PRIORITIES
90+
///
91+
const UNMANAGED_INTERRUPT_PRIORITIES: &'static [InterruptPriority] = &[];
6992
}
7093

7194
macro_rules! define_kernel_tests {
@@ -159,6 +182,7 @@ pub mod kernel_tests {
159182
(mod interrupt_misc {}, "interrupt_misc"),
160183
(mod interrupt_priority {}, "interrupt_priority"),
161184
(mod interrupt_task_activate {}, "interrupt_task_activate"),
185+
(mod interrupt_unmanaged {}, "interrupt_unmanaged"),
162186
(mod priority_boost {}, "priority_boost"),
163187
(mod semaphore_interrupt_handler {}, "semaphore_interrupt_handler"),
164188
(mod semaphore_misc {}, "semaphore_misc"),

0 commit comments

Comments
 (0)