Commit e128f3c5 authored by Ioannis Glaropoulos's avatar Ioannis Glaropoulos
Browse files

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: default avatarIoannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
parent eddf058e
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -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);
+27 −7
Original line number Diff line number Diff line
@@ -24,12 +24,14 @@ struct k_timer timer;
 * to be in priority 0.
 */
#if defined(CONFIG_ARM)
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
#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)
{