From fab47c807126d83bee9b17ccba358504b8e6ec2b Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Tue, 20 Aug 2024 08:52:41 -0500 Subject: [PATCH] Fix Cmsis irq regression (#1821) * #1817 fix regression with CMSIS interrupt renaming --- .../cmsis/include/cmsis/rename_exceptions.h | 88 ++++---- src/rp2_common/pico_crt0/crt0.S | 195 ++++++++++++++++-- test/cmsis_test/cmsis_test.c | 16 +- 3 files changed, 237 insertions(+), 62 deletions(-) diff --git a/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h b/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h index e825473da..0db37f4ca 100644 --- a/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h +++ b/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h @@ -55,50 +55,50 @@ #define isr_svcall SVC_Handler #define isr_pendsv PendSV_Handler #define isr_systick SysTick_Handler -#define isr_irq0 TIMER0_IRQ_0_IRQn -#define isr_irq1 TIMER0_IRQ_1_IRQn -#define isr_irq2 TIMER0_IRQ_2_IRQn -#define isr_irq3 TIMER0_IRQ_3_IRQn -#define isr_irq4 TIMER1_IRQ_0_IRQn -#define isr_irq5 TIMER1_IRQ_1_IRQn -#define isr_irq6 TIMER1_IRQ_2_IRQn -#define isr_irq7 TIMER1_IRQ_3_IRQn -#define isr_irq8 PWM_IRQ_WRAP_0_IRQn -#define isr_irq9 PWM_IRQ_WRAP_1_IRQn -#define isr_irq10 DMA_IRQ_0_IRQn -#define isr_irq11 DMA_IRQ_1_IRQn -#define isr_irq12 DMA_IRQ_2_IRQn -#define isr_irq13 DMA_IRQ_3_IRQn -#define isr_irq14 USBCTRL_IRQ_IRQn -#define isr_irq15 PIO0_IRQ_0_IRQn -#define isr_irq16 PIO0_IRQ_1_IRQn -#define isr_irq17 PIO1_IRQ_0_IRQn -#define isr_irq18 PIO1_IRQ_1_IRQn -#define isr_irq19 PIO2_IRQ_0_IRQn -#define isr_irq20 PIO2_IRQ_1_IRQn -#define isr_irq21 IO_IRQ_BANK0_IRQn -#define isr_irq22 IO_IRQ_BANK0_NS_IRQn -#define isr_irq23 IO_IRQ_QSPI_IRQn -#define isr_irq24 IO_IRQ_QSPI_NS_IRQn -#define isr_irq25 SIO_IRQ_FIFO_IRQn -#define isr_irq26 SIO_IRQ_BELL_IRQn -#define isr_irq27 SIO_IRQ_FIFO_NS_IRQn -#define isr_irq28 SIO_IRQ_BELL_NS_IRQn -#define isr_irq29 SIO_IRQ_MTIMECMP_IRQn -#define isr_irq30 CLOCKS_IRQ_IRQn -#define isr_irq31 SPI0_IRQ_IRQn -#define isr_irq32 SPI1_IRQ_IRQn -#define isr_irq33 UART0_IRQ_IRQn -#define isr_irq34 UART1_IRQ_IRQn -#define isr_irq35 ADC_IRQ_FIFO_IRQn -#define isr_irq36 I2C0_IRQ_IRQn -#define isr_irq37 I2C1_IRQ_IRQn -#define isr_irq38 OTP_IRQ_IRQn -#define isr_irq39 TRNG_IRQ_IRQn -#define isr_irq42 PLL_SYS_IRQ_IRQn -#define isr_irq43 PLL_USB_IRQ_IRQn -#define isr_irq44 POWMAN_IRQ_POW_IRQn -#define isr_irq45 POWMAN_IRQ_TIMER_IRQn +#define isr_irq0 TIMER0_IRQ_0_Handler +#define isr_irq1 TIMER0_IRQ_1_Handler +#define isr_irq2 TIMER0_IRQ_2_Handler +#define isr_irq3 TIMER0_IRQ_3_Handler +#define isr_irq4 TIMER1_IRQ_0_Handler +#define isr_irq5 TIMER1_IRQ_1_Handler +#define isr_irq6 TIMER1_IRQ_2_Handler +#define isr_irq7 TIMER1_IRQ_3_Handler +#define isr_irq8 PWM_IRQ_WRAP_0_Handler +#define isr_irq9 PWM_IRQ_WRAP_1_Handler +#define isr_irq10 DMA_IRQ_0_Handler +#define isr_irq11 DMA_IRQ_1_Handler +#define isr_irq12 DMA_IRQ_2_Handler +#define isr_irq13 DMA_IRQ_3_Handler +#define isr_irq14 USBCTRL_IRQ_Handler +#define isr_irq15 PIO0_IRQ_0_Handler +#define isr_irq16 PIO0_IRQ_1_Handler +#define isr_irq17 PIO1_IRQ_0_Handler +#define isr_irq18 PIO1_IRQ_1_Handler +#define isr_irq19 PIO2_IRQ_0_Handler +#define isr_irq20 PIO2_IRQ_1_Handler +#define isr_irq21 IO_IRQ_BANK0_Handler +#define isr_irq22 IO_IRQ_BANK0_NS_Handler +#define isr_irq23 IO_IRQ_QSPI_Handler +#define isr_irq24 IO_IRQ_QSPI_NS_Handler +#define isr_irq25 SIO_IRQ_FIFO_Handler +#define isr_irq26 SIO_IRQ_BELL_Handler +#define isr_irq27 SIO_IRQ_FIFO_NS_Handler +#define isr_irq28 SIO_IRQ_BELL_NS_Handler +#define isr_irq29 SIO_IRQ_MTIMECMP_Handler +#define isr_irq30 CLOCKS_IRQ_Handler +#define isr_irq31 SPI0_IRQ_Handler +#define isr_irq32 SPI1_IRQ_Handler +#define isr_irq33 UART0_IRQ_Handler +#define isr_irq34 UART1_IRQ_Handler +#define isr_irq35 ADC_IRQ_FIFO_Handler +#define isr_irq36 I2C0_IRQ_Handler +#define isr_irq37 I2C1_IRQ_Handler +#define isr_irq38 OTP_IRQ_Handler +#define isr_irq39 TRNG_IRQ_Handler +#define isr_irq42 PLL_SYS_IRQ_Handler +#define isr_irq43 PLL_USB_IRQ_Handler +#define isr_irq44 POWMAN_IRQ_POW_Handler +#define isr_irq45 POWMAN_IRQ_TIMER_Handler #endif #endif diff --git a/src/rp2_common/pico_crt0/crt0.S b/src/rp2_common/pico_crt0/crt0.S index 9bf12631a..e408b7ded 100644 --- a/src/rp2_common/pico_crt0/crt0.S +++ b/src/rp2_common/pico_crt0/crt0.S @@ -52,17 +52,99 @@ __vectors: // we don't include any IRQ vectors; we will initialize them during runtime_init in the RAM vector table #else -.altmacro -.macro isr_irqx irq_num -.word isr_irq\irq_num +.macro if_irq_word num func +.if \num < NUM_IRQS +.word \func +.endif .endm -.set irq_num, 0 -.rept NUM_IRQS -isr_irqx %irq_num -.set irq_num, irq_num + 1 -.endr - +// we include a lot of these to allow for different number of IRQs. +// if_irq_word will only include IRQs that are valid, but we can't +// use a macro loop because isr_irqx MUST appear in the source +// as CMSIS rename exceptions #defines it to another value +if_irq_word 0 isr_irq0 +if_irq_word 1 isr_irq1 +if_irq_word 2 isr_irq2 +if_irq_word 3 isr_irq3 +if_irq_word 4 isr_irq4 +if_irq_word 5 isr_irq5 +if_irq_word 6 isr_irq6 +if_irq_word 7 isr_irq7 +if_irq_word 8 isr_irq8 +if_irq_word 9 isr_irq9 +if_irq_word 10 isr_irq10 +if_irq_word 11 isr_irq11 +if_irq_word 12 isr_irq12 +if_irq_word 13 isr_irq13 +if_irq_word 14 isr_irq14 +if_irq_word 15 isr_irq15 +if_irq_word 16 isr_irq16 +if_irq_word 17 isr_irq17 +if_irq_word 18 isr_irq18 +if_irq_word 19 isr_irq19 +if_irq_word 20 isr_irq20 +if_irq_word 21 isr_irq21 +if_irq_word 22 isr_irq22 +if_irq_word 23 isr_irq23 +if_irq_word 24 isr_irq24 +if_irq_word 25 isr_irq25 +if_irq_word 26 isr_irq26 +if_irq_word 27 isr_irq27 +if_irq_word 28 isr_irq28 +if_irq_word 29 isr_irq29 +if_irq_word 30 isr_irq30 +if_irq_word 31 isr_irq31 +if_irq_word 32 isr_irq32 +if_irq_word 33 isr_irq33 +if_irq_word 34 isr_irq34 +if_irq_word 35 isr_irq35 +if_irq_word 36 isr_irq36 +if_irq_word 37 isr_irq37 +if_irq_word 38 isr_irq38 +if_irq_word 39 isr_irq39 +if_irq_word 40 isr_irq40 +if_irq_word 41 isr_irq41 +if_irq_word 42 isr_irq42 +if_irq_word 43 isr_irq43 +if_irq_word 44 isr_irq44 +if_irq_word 45 isr_irq45 +if_irq_word 46 isr_irq46 +if_irq_word 47 isr_irq47 +if_irq_word 48 isr_irq48 +if_irq_word 49 isr_irq49 +if_irq_word 50 isr_irq50 +if_irq_word 51 isr_irq51 +if_irq_word 52 isr_irq52 +if_irq_word 53 isr_irq53 +if_irq_word 54 isr_irq54 +if_irq_word 55 isr_irq55 +if_irq_word 56 isr_irq56 +if_irq_word 57 isr_irq57 +if_irq_word 58 isr_irq58 +if_irq_word 59 isr_irq59 +if_irq_word 60 isr_irq60 +if_irq_word 61 isr_irq61 +if_irq_word 62 isr_irq62 +if_irq_word 63 isr_irq63 +if_irq_word 64 isr_irq64 +if_irq_word 65 isr_irq65 +if_irq_word 66 isr_irq66 +if_irq_word 67 isr_irq67 +if_irq_word 68 isr_irq68 +if_irq_word 69 isr_irq69 +if_irq_word 70 isr_irq70 +if_irq_word 71 isr_irq71 +if_irq_word 72 isr_irq72 +if_irq_word 73 isr_irq73 +if_irq_word 74 isr_irq74 +if_irq_word 75 isr_irq75 +if_irq_word 76 isr_irq76 +if_irq_word 77 isr_irq77 +if_irq_word 78 isr_irq78 +if_irq_word 79 isr_irq79 +#if NUM_IRQS > 80 +#error more IRQ entries required +#endif #endif // all default exception handlers do nothing, and we can check for them being set to our @@ -93,6 +175,7 @@ decl_isr_bkpt isr_systick .global __default_isrs_end __default_isrs_end: +.altmacro .macro decl_isr name #if !PICO_NO_STORED_VECTOR_TABLE | PICO_NO_FLASH // We declare a weak label, so user can override @@ -105,15 +188,95 @@ __default_isrs_end: \name: .endm -.macro decl_isrx irq_num -decl_isr isr_irq\irq_num +.macro if_irq_decl num func +.if \num < NUM_IRQS +decl_isr \func +.endif .endm -.set irq_num, 0 -.rept NUM_IRQS -decl_isrx %irq_num -.set irq_num, irq_num + 1 -.endr +if_irq_decl 0 isr_irq0 +if_irq_decl 1 isr_irq1 +if_irq_decl 2 isr_irq2 +if_irq_decl 3 isr_irq3 +if_irq_decl 4 isr_irq4 +if_irq_decl 5 isr_irq5 +if_irq_decl 6 isr_irq6 +if_irq_decl 7 isr_irq7 +if_irq_decl 8 isr_irq8 +if_irq_decl 9 isr_irq9 +if_irq_decl 10 isr_irq10 +if_irq_decl 11 isr_irq11 +if_irq_decl 12 isr_irq12 +if_irq_decl 13 isr_irq13 +if_irq_decl 14 isr_irq14 +if_irq_decl 15 isr_irq15 +if_irq_decl 16 isr_irq16 +if_irq_decl 17 isr_irq17 +if_irq_decl 18 isr_irq18 +if_irq_decl 19 isr_irq19 +if_irq_decl 20 isr_irq20 +if_irq_decl 21 isr_irq21 +if_irq_decl 22 isr_irq22 +if_irq_decl 23 isr_irq23 +if_irq_decl 24 isr_irq24 +if_irq_decl 25 isr_irq25 +if_irq_decl 26 isr_irq26 +if_irq_decl 27 isr_irq27 +if_irq_decl 28 isr_irq28 +if_irq_decl 29 isr_irq29 +if_irq_decl 30 isr_irq30 +if_irq_decl 31 isr_irq31 +if_irq_decl 32 isr_irq32 +if_irq_decl 33 isr_irq33 +if_irq_decl 34 isr_irq34 +if_irq_decl 35 isr_irq35 +if_irq_decl 36 isr_irq36 +if_irq_decl 37 isr_irq37 +if_irq_decl 38 isr_irq38 +if_irq_decl 39 isr_irq39 +if_irq_decl 40 isr_irq40 +if_irq_decl 41 isr_irq41 +if_irq_decl 42 isr_irq42 +if_irq_decl 43 isr_irq43 +if_irq_decl 44 isr_irq44 +if_irq_decl 45 isr_irq45 +if_irq_decl 46 isr_irq46 +if_irq_decl 47 isr_irq47 +if_irq_decl 48 isr_irq48 +if_irq_decl 49 isr_irq49 +if_irq_decl 50 isr_irq50 +if_irq_decl 51 isr_irq51 +if_irq_decl 52 isr_irq52 +if_irq_decl 53 isr_irq53 +if_irq_decl 54 isr_irq54 +if_irq_decl 55 isr_irq55 +if_irq_decl 56 isr_irq56 +if_irq_decl 57 isr_irq57 +if_irq_decl 58 isr_irq58 +if_irq_decl 59 isr_irq59 +if_irq_decl 60 isr_irq60 +if_irq_decl 61 isr_irq61 +if_irq_decl 62 isr_irq62 +if_irq_decl 63 isr_irq63 +if_irq_decl 64 isr_irq64 +if_irq_decl 65 isr_irq65 +if_irq_decl 66 isr_irq66 +if_irq_decl 67 isr_irq67 +if_irq_decl 68 isr_irq68 +if_irq_decl 69 isr_irq69 +if_irq_decl 70 isr_irq70 +if_irq_decl 71 isr_irq71 +if_irq_decl 72 isr_irq72 +if_irq_decl 73 isr_irq73 +if_irq_decl 74 isr_irq74 +if_irq_decl 75 isr_irq75 +if_irq_decl 76 isr_irq76 +if_irq_decl 77 isr_irq77 +if_irq_decl 78 isr_irq78 +if_irq_decl 79 isr_irq79 +#if NUM_IRQS > 80 +#error more IRQ entries required +#endif // All unhandled USER IRQs fall through to here .global __unhandled_user_irq diff --git a/test/cmsis_test/cmsis_test.c b/test/cmsis_test/cmsis_test.c index bb0bebda6..6e9fdf62c 100644 --- a/test/cmsis_test/cmsis_test.c +++ b/test/cmsis_test/cmsis_test.c @@ -5,23 +5,35 @@ #else #include "RP2350.h" #endif -#include "pico/stdio.h" +#include "pico/stdlib.h" +#include "hardware/irq.h" __STATIC_FORCEINLINE int some_function(int i) { return __CLZ(i); } -static bool pendsv_called; +static bool pendsv_called, irq_handler_called; void PendSV_Handler(void) { pendsv_called = true; } +void DMA_IRQ_0_Handler(void) { + irq_handler_called = true; + irq_clear(DMA_IRQ_0_IRQn); +} + int main(void) { stdio_init_all(); for(int i=0;i<10;i++) { printf("%d %d\n", i, some_function(i)); } SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; + printf("PENDSV: "); puts(pendsv_called ? "SUCCESS" : "FAILURE"); + printf("DMA_IRQ_0: "); + irq_set_enabled(DMA_IRQ_0_IRQn, true); + irq_set_pending(DMA_IRQ_0_IRQn); + puts(irq_handler_called ? "SUCCESS" : "FAILURE"); + return !(pendsv_called && irq_handler_called); }