Keil Logo

ARM: SPORADIC INTERRUPT PROBLEMS


Information in this article applies to:

  • ARM All Devices
  • ARM Compiler All Variants

SYMPTOM

The interrupt code on my ARM system seems to fail sporadically. Similar code was working fine for years on an 8051 target.

Below is the specific code portion extracted into a test program written with the Keil CARM Compiler for the Keil MCB2100 Evaluation Board:

#include <LPC21xx.h>

unsigned long volatile counter;

/* Timer 0 Interrupt Function */
void tc0 (void) __irq  {
  IOCLR1 = 0xFFFFFFFF;
  counter = 0;
  T0IR        = 1;                         // Clear interrupt flag
  VICVectAddr = 0;                         // Acknowledge Interrupt
}

/* Setup the Timer Counter 0 Interrupt */
void init_timer (void)  {
  T0MR0 = 149999;                          // 10mSec = 150000-1 counts
  T0MCR = 3;                               // Interrupt and Reset on MR0
  T0TCR = 1;                               // Timer0 Enable
  VICVectAddr0 = (unsigned long)tc0;       // set interrupt vector in 0
  VICVectCntl0 = 0x20 | 4;                 // use it for Timer 0 Interrupt
  VICIntEnable = 0x00000010;               // Enable Timer0 Interrupt
}

void main (void) {
  int v;

  IODIR1 = 0x00FF0000;
  IOCLR1 = 0x00FF0000;
  init_timer();

  while(1)  {
    v = (counter << 8) & 0xFF0000;         // the true I/O pins
    counter++;

    IOSET1 = v;                            // turn on LED
    IOCLR1 = ~v;                           // turn off LED
  }
}

CAUSE

In contrast to 8051 or C166, the C statement counter++ does not translate into a single CPU instruction. Therefore, this C statement is not atomic and interrupts may happen in the middle of the increment. As a result, the statement counter = 0; in your interrupt code may not really reset the counter value.

RESOLUTION

Disable the timer interrupt before you update the counter variable in your main application. This is shown in the program sequence below:

/* Default Interrupt Function: may be called when timer ISR is disabled */
void DefISR (void) __irq  {
  ;
}

/* Timer 0 Interrupt Function: called when timer ISR is enabled */
void tc0 (void) __irq  {
  IOCLR1 = 0xFFFFFFFF;
  counter = 0;
  T0IR        = 1;                         // Clear interrupt flag
  VICVectAddr = 0;                         // Acknowledge Interrupt
}

/* Setup the Timer Counter 0 Interrupt */
void init_timer (void)  {
  T0MR0 = 149999;                          // 10mSec = 150000-1 counts
  T0MCR = 3;                               // Interrupt and Reset on MR0
  T0TCR = 1;                               // Timer0 Enable
  VICVectAddr0 = (unsigned long)tc0;       // set interrupt vector in 0
  VICVectCntl0 = 0x20 | 4;                 // use it for Timer 0 Interrupt
  VICIntEnable = 0x00000010;               // Enable Timer0 Interrupt
}


void main (void) {
  int v;

  IODIR1 = 0x00FF0000;
  IOCLR1 = 0x00FF0000;
  init_timer();
    VICDefVectAddr = (unsigned long) DefISR;   // ISR for un-assigned VIC interrupts

  while(1)  {
    VICIntEnClr |= 0x00000010;             // Disable Timer0 Interrupt
// put some instructions to ensure that the interrupt is blocked (pipeline effects)!
    v = (counter << 8) & 0xFF0000;         // the true I/O pins
    counter++;
    VICIntEnable |= 0x00000010;            // Enable Timer0 Interrupt

    IOSET1 = v;                            // turn on LED
    IOCLR1 = ~v;                           // turn off LED
  }
}

The VIC (Vectored Interrupt Controller) of the ARM device may still accept interrupts even when they are disabled. Therefore you must implement a default interrupt service routine as shown above.

MORE INFORMATION

  • ARM Instruction Set User's Guide
  • ARM Architecture Reference Manuals

SEE ALSO

FORUM THREADS

The following Discussion Forum threads may provide information related to this topic.

Last Reviewed: Thursday, July 27, 2006


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  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.