I often see something like this void UART2_IRQHandler(void) __irq
, and I wonder why __irq is used when declaring interrupt handler, is it required or handler can work without it?
-
\$\begingroup\$ It is instruction to compiler. Have a look at Assembly code generated with and without __irq... Lot of interesting things happen due to __irq (which are explained in the answers) \$\endgroup\$– SwanandCommented Apr 23, 2015 at 10:45
-
\$\begingroup\$ An issue i faced when i omitted the __irq to my Handler was that, when I rentered my ISR Handler for the second time(first time worked well), it changed the mode to IRQ but never called my ISR Handler. When I tried with __irq, it worked well for the second call. \$\endgroup\$– AlphaGokuCommented Mar 20, 2020 at 11:43
3 Answers
Basically, an interrupt service routine written in C is simply a function that takes no arguments and doesn't return anything void someKindOfIsr(void)
.
__irq
is a C language extension for your compiler that is used to generate special entry and/or exit assembly instructions for handling interrupts. For instance, the return instruction may be different if you are returning from an interrupt rather than a simple function to clear some type of interrupt status register.
Whether it is necessary or not depends on what ARM architecture you are working with. A quick way to find out if it is necessary for your platform is to examine the assembly produced both with and without the __irq
keyword.
Even if the listing file is exactly the same both with and without the __irq
keyword, you may want to consider leaving the __irq
keyword in place for clarity and for portability to some future platform.
-
\$\begingroup\$ Thanks for the answer, now I know what is the purpose of __irq. \$\endgroup\$– LakiCommented Apr 21, 2015 at 6:27
Some microcontrollers require a different handling of the stack and return for interrupt handling functions as for normal functions.
For ARM controllers a normal entry to a subroutine uses a PUSH to save stuff on the stack, and on exit of the subroutine you would POP the saved state back and leave the subroutine. (ARM Assembly Reference page 65)
For an exception handler on modern ARM platforms the state is automatically pushed on the stack, so the compiler doesn't need to create a PUSH instruction on function entry. Also the exit from a exception handler can look different from a normal one, the ARMv7-M architecture will return from an exception if either POP/LDM, LDR or BX will load a value of 0xFXXXXXXX
into the program counter (PC).
So the __irq
tells the compiler that this functions entry and exit might require special treatment, and special depending on the set target (for 8051 I think there was RET for normal return and RETI for interrupt return).
No, it cant work without _irq. it's a general format. you need to follow this. otherwise it wont work.
-
7\$\begingroup\$ This is a bit thin for an answer. Can you explain exactly what
__irq
does in the compiler? \$\endgroup\$ Commented Apr 20, 2015 at 14:46