Skip to content

Commit e128f3c

Browse files
committed
tests: kernel: interrupt: make test work with any available NVIC IRQ
This commit re-works the test for the ARM architecture, so that it can work with any available NVIC IRQ, not bound to use the last 2 NVIC lines. It makes use of the dynamic IRQ feature. Signed-off-by: Ioannis Glaropoulos <[email protected]>
1 parent eddf058 commit e128f3c

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

tests/kernel/interrupt/src/interrupt.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,39 @@
1111

1212
#if defined(CONFIG_ARM)
1313
#include <arch/arm/cortex_m/cmsis.h>
14+
15+
static u32_t get_available_nvic_line(u32_t initial_offset)
16+
{
17+
int i;
18+
19+
for (i = initial_offset - 1; i >= 0; i--) {
20+
21+
if (NVIC_GetEnableIRQ(i) == 0) {
22+
/*
23+
* Interrupts configured statically with IRQ_CONNECT(.)
24+
* are automatically enabled. NVIC_GetEnableIRQ()
25+
* returning false, here, implies that the IRQ line is
26+
* either not implemented or it is not enabled, thus,
27+
* currently not in use by Zephyr.
28+
*/
29+
30+
/* Set the NVIC line to pending. */
31+
NVIC_SetPendingIRQ(i);
32+
33+
if (NVIC_GetPendingIRQ(i)) {
34+
/* If the NVIC line is pending, it is
35+
* guaranteed that it is implemented.
36+
*/
37+
break;
38+
}
39+
}
40+
}
41+
42+
zassert_true(i >= 0, "No available IRQ line\n");
43+
44+
return i;
45+
}
46+
1447
static void trigger_irq(int irq)
1548
{
1649
printk("Triggering irq : %d\n", irq);

tests/kernel/interrupt/src/nested_irq.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ struct k_timer timer;
2424
* to be in priority 0.
2525
*/
2626
#if defined(CONFIG_ARM)
27-
#define ISR0_PRIO 2
28-
#define ISR1_PRIO 1
27+
u32_t irq_line_0;
28+
u32_t irq_line_1;
29+
#define ISR0_PRIO 2
30+
#define ISR1_PRIO 1
2931
#else
30-
#define ISR0_PRIO 1
31-
#define ISR1_PRIO 0
32-
#endif
32+
#define ISR0_PRIO 1
33+
#define ISR1_PRIO 0
34+
#endif /* CONFIG_ARM */
3335

3436
#define MS_TO_US(ms) (K_MSEC(ms) * USEC_PER_MSEC)
3537
volatile u32_t new_val;
@@ -53,15 +55,20 @@ void isr1(void *param)
5355
static void handler(struct k_timer *timer)
5456
{
5557
ARG_UNUSED(timer);
58+
#if defined(CONFIG_ARM)
59+
irq_enable(irq_line_1);
60+
trigger_irq(irq_line_1);
61+
#else
5662
irq_enable(IRQ_LINE(ISR1_OFFSET));
5763
trigger_irq(IRQ_LINE(ISR1_OFFSET));
64+
#endif /* CONFIG_ARM */
5865
}
5966
#else
6067
void handler(void)
6168
{
6269
ztest_test_skip();
6370
}
64-
#endif
71+
#endif /* NO_TRIGGER_FROM_SW */
6572

6673
void isr0(void *param)
6774
{
@@ -82,21 +89,34 @@ void isr0(void *param)
8289
#ifndef NO_TRIGGER_FROM_SW
8390
void test_nested_isr(void)
8491
{
92+
#if defined(CONFIG_ARM)
93+
irq_line_0 = get_available_nvic_line(CONFIG_NUM_IRQS);
94+
irq_line_1 = get_available_nvic_line(irq_line_0);
95+
z_arch_irq_connect_dynamic(irq_line_0, ISR0_PRIO, isr0, NULL, 0);
96+
z_arch_irq_connect_dynamic(irq_line_1, ISR1_PRIO, isr1, NULL, 0);
97+
#else
8598
IRQ_CONNECT(IRQ_LINE(ISR0_OFFSET), ISR0_PRIO, isr0, NULL, 0);
8699
IRQ_CONNECT(IRQ_LINE(ISR1_OFFSET), ISR1_PRIO, isr1, NULL, 0);
100+
#endif /* CONFIG_ARM */
87101

88102
k_timer_init(&timer, handler, NULL);
89103
k_timer_start(&timer, DURATION, 0);
104+
105+
#if defined(CONFIG_ARM)
106+
irq_enable(irq_line_0);
107+
trigger_irq(irq_line_0);
108+
#else
90109
irq_enable(IRQ_LINE(ISR0_OFFSET));
91110
trigger_irq(IRQ_LINE(ISR0_OFFSET));
111+
#endif /* CONFIG_ARM */
92112

93113
}
94114
#else
95115
void test_nested_isr(void)
96116
{
97117
ztest_test_skip();
98118
}
99-
#endif
119+
#endif /* NO_TRIGGER_FROM_SW */
100120

101121
static void timer_handler(struct k_timer *timer)
102122
{

0 commit comments

Comments
 (0)