6
\$\begingroup\$

I have created a C++ project for an LPC1227 using LPCExpresso 6.1.0. The project, up until now, builds and runs fine. I have not made any changes to cr_startup_lpc12xx.cpp.

I would like to add a SysTick_Handler(). In my main.cpp I have added a method:

void SysTick_Handler(void)
{
    timerCounter++;  // these variables are all declared globally in main.cpp
    timer_10ms_tick = true;
    if ((timerCounter % 10) == 0)  //every 100ms
    {
        timer_100ms_tick = true;
    }
    if ((timerCounter % 100) == 0)  //every 1000ms
    {
        timer_1000ms_tick = true;
    }
}   

I have also add the following line in my main() method:

SysTick_Config(12000000/100);  

When I run my code via debug, the interrupt is firing, but it is getting stuck in the default SysTick_Handler() that is inside of cr_startup_lpc12xx.cpp (which is just an infinite while loop). If I delete the default SysTick_Handler from cr_startup_lpc12xx.cpp, my program hard faults.

I have looked at the Blinky example (which is C, not C++) and it adds a new handler into main.cpp without deleting the handler from the startup file.

Can anyone suggest why my overriding handler is not being called? Is this a C++ difference?

\$\endgroup\$
1
  • \$\begingroup\$ If you change to normal c file does it work? If you change Blinky example to c++ do you get the same problem? \$\endgroup\$ – geometrikal Dec 17 '13 at 21:37
4
\$\begingroup\$

From https://rowley.zendesk.com/entries/20986562-LPC1114-IRQ-Handlers-in-C-work-in-C-do-not-work

You need to declare your interrupt handler as a C function otherwise the function will not override the default handler.

So for example you could do something like the following to make the declaration work in both C or C++:

#ifdef __cplusplus
extern "C" {
#endif

void irq_handler();

#ifdef __cplusplus
}
#endif

I assume changing irq_handler() in the code above to your SysTick_Handler code will then work. e.g.

extern "C" {
    void SysTick_Handler(void)
    {
        timerCounter++;  // these variables are all declared globally in main.cpp
        timer_10ms_tick = true;
        if ((timerCounter % 10) == 0)  //every 100ms
        {
            timer_100ms_tick = true;
        }
        if ((timerCounter % 100) == 0)  //every 1000ms
        {
            timer_1000ms_tick = true;
        }
    }
}
\$\endgroup\$
0
0
\$\begingroup\$

I don't know if this is true of C++, but in C the default handler must be declared as a weak function in the default declarations. This allows another declaration to override the original one, so your custom handler should not have the weak attribute.

\$\endgroup\$
1
  • \$\begingroup\$ True. It is declared weak. \$\endgroup\$ – TDL Dec 17 '13 at 21:48
0
\$\begingroup\$

I had exactly the same problem once. Yes it is C++ vs C difference. Looks like the maintainers of LPC support libraries did not care for C++ developers. Full answer is here Bug in Keil ARM compiler with interrupt handlers and C++?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.