9

I have a problem with writing interrupt handlers in Keil ARM compiler for LPC1114. When I write program in C++ and specify --cpp compiler option all code from interrupt handlers disappears, it is replaced with infinite loop. I wrote simple program that illustrates my trouble.

#include "LPC11xx.h"           // LPC11xx definitions
#define SYSTICK_DELAY 120000   // for 10 ms systick @ 12MHz osc

void SysTick_Handler(void)
{
  __NOP();
}

int main (void) 
{
  SystemInit();                   // from system_LPC11xx.c
  SysTick_Config(SYSTICK_DELAY);  // from core_cm0.h
  // Loop forever
  while (1) __NOP();
}

When trying to compile this code with --cpp compiler option I get infinite loop in disasm:

SysTick_Handler PROC
            EXPORT  SysTick_Handler           [WEAK]
            B       .
            ENDP

This is the place where __NOP() from above program must be. And it is there when I'm compiling code with --c99 compiler option or without additional options. Keil MDK version is 4.12. Can anyone tell me is there any solution or workaround ?

x4mer
  • 986
  • 1
  • 9
  • 13
  • As your ISR does nothing is it just being optimized away? Perhaps you could try disabling optimization or declaring something `volatile` in it. – Nick T Dec 08 '10 at 14:44
  • Optimization is set to -level0, Optimize for Time - deselected. __NOP() is not nothing. But I also tried changing global vars in interrupt handler or calling for functions. The code provided above was simplified to be just so small to reproduce the problem. – x4mer Dec 08 '10 at 15:02
  • 1
    Filed a technical support request to Keil, will repost here any answer. – x4mer Dec 08 '10 at 15:06
  • Why do you need an __NOP(); call? Can't you just use a simple semicolon? – Kevin Vermeer Dec 08 '10 at 15:34

1 Answers1

16

The "weak" reference just means that the routine will be replaced by a routine in your code of the same name. When using C this is simple, the names will always be identical but C++ name mangles the functions (for function overloading etc) so the compiled name will probably not match the default ISR name. You need to wrap the function (or at least a forward reference, I'm not sure of specifics I mostly work in C) in an extern "C" wrapper to force the compiler to not mangle the name.

extern "C" {
  void SysTick_Handler(void)
  {
    // do whatever
  }
}
timrorr
  • 1,713
  • 10
  • 10
  • 3
    Thank you. This works exactly as you wrote in example. And also I can declare function in header file as extern "C" void SysTick_Handler(void); and later write my interrupt handler in classical form i.e. without extern "C". – x4mer Dec 10 '10 at 14:22
  • Oh my god! Thank you for this great answer! So much time was wasted because of not knowing this ) Thank you once more! –  Feb 12 '11 at 15:34