Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | /* * Copyright (c) 2014 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ #include <ztest.h> #include <arch/cpu.h> #include <arch/arm/cortex_m/cmsis.h> #include <linker/sections.h> struct k_sem sem[3]; /** * * @brief ISR for IRQ0 * * @return N/A */ void isr0(void) { printk("%s ran!\n", __func__); k_sem_give(&sem[0]); _IntExit(); } /** * * @brief ISR for IRQ1 * * @return N/A */ void isr1(void) { printk("%s ran!\n", __func__); k_sem_give(&sem[1]); _IntExit(); } /** * * @brief ISR for IRQ2 * * @return N/A */ void isr2(void) { printk("%s ran!\n", __func__); k_sem_give(&sem[2]); _IntExit(); } /** * @defgroup kernel_interrupt_tests Interrupts * @ingroup all_tests * @{ */ /** * @brief Test installation of ISRs directly in the vector table * * @details Test validates the arm irq vector table. We create a * irq vector table with the address of the interrupt handler. We write * into the Software Trigger Interrupt Register(STIR) or calling * NVIC_SetPendingIRQ(), to trigger the pending interrupt. And we check * that the corresponding interrupt handler is getting called or not. * * @see irq_enable(), _irq_priority_set(), NVIC_SetPendingIRQ() * */ void test_arm_irq_vector_table(void) { printk("Test Cortex-M3 IRQ installed directly in vector table\n"); for (int ii = 0; ii < 3; ii++) { irq_enable(ii); _irq_priority_set(ii, 0, 0); k_sem_init(&sem[ii], 0, UINT_MAX); } zassert_true((k_sem_take(&sem[0], K_NO_WAIT) || k_sem_take(&sem[1], K_NO_WAIT) || k_sem_take(&sem[2], K_NO_WAIT)), NULL); for (int ii = 0; ii < 3; ii++) { #if defined(CONFIG_SOC_TI_LM3S6965_QEMU) /* the QEMU does not simulate the * STIR register: this is a workaround */ NVIC_SetPendingIRQ(ii); #else #if defined(CONFIG_SOC_SERIES_NRF52X) /* The customized solution for nRF52X-based platforms * requires that the RTC1 IRQ line equals 17 and is larger * than the CONFIG_NUM_IRQS. */ __ASSERT(RTC1_IRQn == 17, "RTC1_IRQn != 17. Consider rework manual vector table."); __ASSERT(RTC1_IRQn >= CONFIG_NUM_IRQS, "RTC1_IRQn < NUM_IRQs. Consider rework manual vector table."); #endif /* CONFIG_SOC_SERIES_NRF52X */ NVIC->STIR = ii; #endif } zassert_false((k_sem_take(&sem[0], K_NO_WAIT) || k_sem_take(&sem[1], K_NO_WAIT) || k_sem_take(&sem[2], K_NO_WAIT)), NULL); } #if defined(CONFIG_SOC_SERIES_NRF52X) /* nRF52X-based platforms employ a Hardware RTC peripheral * to implement the Kernel system timer, instead of the ARM Cortex-M * SysTick. Therefore, a pointer to the timer ISR needs to be added in * the custom vector table to handle the timer "tick" interrupts. */ void rtc1_nrf5_isr(void); typedef void (*vth)(void); /* Vector Table Handler */ vth __irq_vector_table _irq_vector_table[RTC1_IRQn + 1] = { isr0, isr1, isr2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, rtc1_nrf5_isr }; #else typedef void (*vth)(void); /* Vector Table Handler */ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { isr0, isr1, isr2 }; #endif /* CONFIG_SOC_SERIES_NRF52X */ /** * @} */ |