From b5908fd89d4631c9eed777e42f55367081babf81 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Wed, 21 Aug 2019 12:03:46 -0700 Subject: [PATCH] tests/kernel/interrupt: Add a simple dynamic interrupt test Platforms which use the GEN_SW_ISR mechanism for interrupt handling can make use of a really simple whitebox trick for verifying that it worked (i.e. that the pointer and argument get placed in the table correctly). Easy and simple way to get some coverage for dynamic IRQs, which is currently entirely missing. Long term we'll want to replace this with a test that uses the API directly and chooses an arch-specific vector to set, and triggers it using arch-specific code, but that's quite a bit more effort and for now we need to land patches to z_irq_connect_dynamic() which show test coverage. Signed-off-by: Andy Ross --- tests/kernel/interrupt/prj.conf | 1 + tests/kernel/interrupt/src/main.c | 51 ++++++++++++++++++++++++++++ tests/kernel/interrupt/testcase.yaml | 9 ++++- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/tests/kernel/interrupt/prj.conf b/tests/kernel/interrupt/prj.conf index 9a75212e89d..c8656e42213 100644 --- a/tests/kernel/interrupt/prj.conf +++ b/tests/kernel/interrupt/prj.conf @@ -1,2 +1,3 @@ CONFIG_ZTEST=y CONFIG_IRQ_OFFLOAD=y +CONFIG_DYNAMIC_INTERRUPTS=y diff --git a/tests/kernel/interrupt/src/main.c b/tests/kernel/interrupt/src/main.c index 2b2fce3c48d..713057de748 100644 --- a/tests/kernel/interrupt/src/main.c +++ b/tests/kernel/interrupt/src/main.c @@ -9,9 +9,60 @@ extern void test_nested_isr(void); extern void test_prevent_interruption(void); +extern void z_irq_spurious(void *unused); + +/* Simple whitebox test of dynamic interrupt handlers as implemented + * by the GEN_SW_ISR feature. + */ +#if (defined(CONFIG_DYNAMIC_INTERRUPTS) \ + && defined(CONFIG_GEN_SW_ISR_TABLE)) +#define DYNTEST 1 +#endif + +#ifdef DYNTEST +static void dyn_isr(void *arg) +{ + ARG_UNUSED(arg); +} + +extern struct _isr_table_entry __sw_isr_table _sw_isr_table[]; + +static void do_isr_dynamic(void) +{ + int i; + void *argval; + + for (i = CONFIG_GEN_IRQ_START_VECTOR; i < CONFIG_NUM_IRQS; i++) { + if (_sw_isr_table[i].isr == z_irq_spurious) { + break; + } + } + + zassert_true(_sw_isr_table[i].isr == z_irq_spurious, + "could not find slot for dynamic isr"); + + argval = &i; + z_arch_irq_connect_dynamic(i, 0, dyn_isr, argval, 0); + + zassert_true(_sw_isr_table[i].isr == dyn_isr && + _sw_isr_table[i].arg == argval, + "dynamic isr did not install successfully"); +} +#endif /* DYNTEST */ + +void test_isr_dynamic(void) +{ +#ifdef DYNTEST + do_isr_dynamic(); +#else + ztest_test_skip(); +#endif +} + void test_main(void) { ztest_test_suite(interrupt_feature, + ztest_unit_test(test_isr_dynamic), ztest_unit_test(test_nested_isr), ztest_unit_test(test_prevent_interruption) ); diff --git a/tests/kernel/interrupt/testcase.yaml b/tests/kernel/interrupt/testcase.yaml index 646c6ecee63..c061cef4835 100644 --- a/tests/kernel/interrupt/testcase.yaml +++ b/tests/kernel/interrupt/testcase.yaml @@ -1,7 +1,14 @@ tests: arch.interrupt: - arch_exclude: nios2 riscv32 + arch_exclude: nios2 riscv32 arc qemu_x86 qemu_x86_coverage qemu_x86_64 platform_exclude: hexiwear_kw40z frdm_kw41z frdm_kl25z nucleo_f103rb nucleo_f091rc olimexino_stm32 usb_kw24d512 stm32_min_dev_blue stm32_min_dev_black v2m_beetle tags: interrupt + + # Platforms without relevant (gen isr) dynamic interrupt support: + arch.interrupt.nodyn: + arch_whitelist: arc qemu_x86 qemu_x86_coverage qemu_x86_64 + tags: interrupt + extra_configs: + - CONFIG_DYNAMIC_INTERRUPTS=n