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 <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
Ioannis Glaropoulos 2019-08-27 23:04:01 +02:00
commit e128f3c5d9
2 changed files with 60 additions and 7 deletions

View file

@ -11,6 +11,39 @@
#if defined(CONFIG_ARM)
#include <arch/arm/cortex_m/cmsis.h>
static u32_t get_available_nvic_line(u32_t initial_offset)
{
int i;
for (i = initial_offset - 1; i >= 0; i--) {
if (NVIC_GetEnableIRQ(i) == 0) {
/*
* Interrupts configured statically with IRQ_CONNECT(.)
* are automatically enabled. NVIC_GetEnableIRQ()
* returning false, here, implies that the IRQ line is
* either not implemented or it is not enabled, thus,
* currently not in use by Zephyr.
*/
/* Set the NVIC line to pending. */
NVIC_SetPendingIRQ(i);
if (NVIC_GetPendingIRQ(i)) {
/* If the NVIC line is pending, it is
* guaranteed that it is implemented.
*/
break;
}
}
}
zassert_true(i >= 0, "No available IRQ line\n");
return i;
}
static void trigger_irq(int irq)
{
printk("Triggering irq : %d\n", irq);

View file

@ -24,12 +24,14 @@ struct k_timer timer;
* to be in priority 0.
*/
#if defined(CONFIG_ARM)
#define ISR0_PRIO 2
#define ISR1_PRIO 1
u32_t irq_line_0;
u32_t irq_line_1;
#define ISR0_PRIO 2
#define ISR1_PRIO 1
#else
#define ISR0_PRIO 1
#define ISR1_PRIO 0
#endif
#define ISR0_PRIO 1
#define ISR1_PRIO 0
#endif /* CONFIG_ARM */
#define MS_TO_US(ms) (K_MSEC(ms) * USEC_PER_MSEC)
volatile u32_t new_val;
@ -53,15 +55,20 @@ void isr1(void *param)
static void handler(struct k_timer *timer)
{
ARG_UNUSED(timer);
#if defined(CONFIG_ARM)
irq_enable(irq_line_1);
trigger_irq(irq_line_1);
#else
irq_enable(IRQ_LINE(ISR1_OFFSET));
trigger_irq(IRQ_LINE(ISR1_OFFSET));
#endif /* CONFIG_ARM */
}
#else
void handler(void)
{
ztest_test_skip();
}
#endif
#endif /* NO_TRIGGER_FROM_SW */
void isr0(void *param)
{
@ -82,13 +89,26 @@ void isr0(void *param)
#ifndef NO_TRIGGER_FROM_SW
void test_nested_isr(void)
{
#if defined(CONFIG_ARM)
irq_line_0 = get_available_nvic_line(CONFIG_NUM_IRQS);
irq_line_1 = get_available_nvic_line(irq_line_0);
z_arch_irq_connect_dynamic(irq_line_0, ISR0_PRIO, isr0, NULL, 0);
z_arch_irq_connect_dynamic(irq_line_1, ISR1_PRIO, isr1, NULL, 0);
#else
IRQ_CONNECT(IRQ_LINE(ISR0_OFFSET), ISR0_PRIO, isr0, NULL, 0);
IRQ_CONNECT(IRQ_LINE(ISR1_OFFSET), ISR1_PRIO, isr1, NULL, 0);
#endif /* CONFIG_ARM */
k_timer_init(&timer, handler, NULL);
k_timer_start(&timer, DURATION, 0);
#if defined(CONFIG_ARM)
irq_enable(irq_line_0);
trigger_irq(irq_line_0);
#else
irq_enable(IRQ_LINE(ISR0_OFFSET));
trigger_irq(IRQ_LINE(ISR0_OFFSET));
#endif /* CONFIG_ARM */
}
#else
@ -96,7 +116,7 @@ void test_nested_isr(void)
{
ztest_test_skip();
}
#endif
#endif /* NO_TRIGGER_FROM_SW */
static void timer_handler(struct k_timer *timer)
{