Keil Logo

Interrupt Functions

RTX can work with interrupt functions in parallel. However, it is better to avoid IRQ nesting. Good programming techniques use short interrupt functions that send signals or messages to RTOS tasks. With this practice, interrupt nesting becomes unimportant. This avoids common problems with nested interrupts where the user mode stack usage becomes unpredictable.

The following figure shows how interrupts should be handled with tasks in the RTX kernel system. An IRQ function can send a signal or message to start a high priority task.

interrupt timings

Interrupt functions are added to an ARM application in the same way as in any other non-RTX projects.

Note

  • The FIQ interrupts are never disabled by the RTX kernel.
  • You cannot call the isr_ library functions from the FIQ interrupt function.

The following example shows how to use interrupts with the RTX kernel. The interrupt function, ext0_int, sends an event to process_task and exits. The task process_task processes the external interrupt event. In this example, process_task is simple and only counts the number of interrupt events.

#define EVT_KEY 0x0001

OS_TID pr_task;
int    num_ints;

/*----------------------------------------------------------------------------
 *   External 0 Interrupt Service Routine
 *---------------------------------------------------------------------------*/
void ext0_int (void) __irq  {
  isr_evt_set (EVT_KEY, pr_task);      /* Send event to 'process_task'       */
  EXTINT      = 0x01;                  /* Acknowledge Interrupt              */
  VICVectAddr = 0;
}

/*----------------------------------------------------------------------------
 *   Task 'process_task'
 *---------------------------------------------------------------------------*/
__task void process_task (void) {
  num_ints = 0;
  while (1) {
    os_evt_wait_or (EVT_KEY, 0xffff);
    num_ints++;
  }
}

/*----------------------------------------------------------------------------
 *   Task 'init_task'
 *---------------------------------------------------------------------------*/
__task void init_task (void) {
  PINSEL1 &= ~0x00000003;              /* Enable EINT0                       */
  PINSEL1 |=  0x00000001;
  EXTMODE  = 0x03;                     /* Edge triggered lo->hi transition   */
  EXTPOLAR = 0x03;

  pr_task = os_tsk_create (process_task, 100);

  VICVectAddr14  = (U32)eint0_int;     /* Task started, Enable interrupts    */
  VICVectCntl14  = 0x20 | 14;

  os_tsk_delete_self ();               /* Terminate this task                */
}
  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.