Keil Logo

__irq: Interrupt

The CARM Compiler supports C interrupt functions and eliminates the need to write interrupt service routines in assembly language. Interrupt functions are defined using the __irq function attribute.

void funcname (void) __irq


funcname is the name of the function.
__irq indicates the function is an interrupt function.

The __irq attribute affects the generated code of the function as follows:

  • The function is generated using ARM instructions even if the THUMB directive is specified.
  • On function entry, the registers R0-R12 (when modified) are saved on the stack.
  • When exiting the function, all register contents saved on the stack are restored.
  • The SUBS PC,R14,#4 instruction is used to return from the __irq function.

For ARM devices without a Vectored Interrupt Controller (VIC), when an interrupt is triggered, the ARM device jumps to the __irq vector location. On such devices, only one __irq function is possible. By default, the CPU startup code (STARTUP.S) jumps to the function named IRQ_Handler. So, if you name your __irq function IRQ_Handler, no changes to the STARTUP.S file are required.

For ARM devices with a Vectored Interrupt Controller (VIC), when an interrupt is triggered, the address of the __irq function is written into the interrupt vector register of the VIC. On such devices, seperate __irq functions for each interrupt source may be created.

The following example shows how to use the __irq attribute without a VIC. The code sequences generated are shown in the Assembler Listing.

stmt  level    source

   1          /*
   2           *  IRQ Handler for ADuC7000 Timer0 Interrupt
   3           */
   5          #include <ADuC7024.H>
   7          volatile int T0_ticks;
   9          void IRQ_Handler (void)  __irq  {
  10   1        if (IRQSIG & 0x00000004)  {   // Timer0 Interrupt
  11   2          T0CLRI = 1;
  12   2          T0_ticks++;
  13   2        }
  14   1      }


 PUBLIC         IRQ_Handler?A
 PUBLIC         T0_ticks

*** DATA SEGMENT '?DT0?irq':
 00000000          T0_ticks:
 00000000            DS          4

*** CODE SEGMENT '?PR?IRQ_Handler?A?irq':
    9: void IRQ_Handler (void)  __irq  {
 00000000  E92D0003  STMDB       R13!,{R0-R1}
   10:   if (IRQSIG & 0x00000004)  {   // Timer0 Interrupt
 00000004  E5100000  LDR         R0,=0xFFFF0004
 00000008  E5900000  LDR         R0,[R0,#0x0]
 0000000C  E3A01004  MOV         R1,#0x4
 00000010  E1100001  TST         R0,R1
 00000014  0A000006  BEQ         L_1  ; Targ=0x34
   11:     T0CLRI = 1;
 00000018  E3A01001  MOV         R1,#0x1
 0000001C  E5100000  LDR         R0,=0xFFFF030C
 00000020  E5801000  STR         R1,[R0,#0x0]
   12:     T0_ticks++;
 00000024  E5100000  LDR         R0,=T0_ticks ; T0_ticks
 00000028  E5901000  LDR         R1,[R0,#0x0] ; T0_ticks
 0000002C  E2811001  ADD         R1,R1,#0x0001
 00000030  E5801000  STR         R1,[R0,#0x0] ; T0_ticks
   13:   }
 00000034          L_1:
 00000034  E8BD0003  LDMIA       R13!,{R0-R1}
 00000038  E25EF004  SUBS        R15,R14,#0x0004
 0000003C          ENDP ; 'IRQ_Handler?A'


  • The __irq attribute is required when declaring or prototyping external functions. For example:
    extern void func (void) __irq;
  • Passing parameters to an interrupt function is not possible. Any attempt to define an interrupt function with arguments generates an error message.
  • Interrupt function declarations may not include a return value. They must be declared with a void return type. The compiler generates an error message if the return type is not void.
  • The CARM run-time library contains a default IRQ_Handler that generates an endless loop using the B $ instruction.
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.