9
\$\begingroup\$

I set up TIM3 to fire an interrupt in my project and it just wouldn't work. I tried everything I could and still couldn't find whats the problem. Then I created a clean project and copy/pasted only the code that sets up TIM3 and interrupts and it magically worked. I literally wasted half a day trying to find what causes the problem and it turns out... interrupts don't like C++.

I wrote my code in C++ because I needed classes in my project so naturally I renamed all my prject .c files to .cpp and also compile with the --cpp directive. Everything worked fine, no problems so far until I decided to use interrupts. So I renamed everything to .c and everything worked, renamed everything back to cpp and it stopped working.

I use Keil uVision5 and my projects are generated with STM32CubeMX (only RCC config).

Anyone had this happen to them? Any workarounds?

\$\endgroup\$
3
  • 5
    \$\begingroup\$ You may be having issues with C vs C++ linkage - your interrupt handler is probably being subjected to C++ name mangling, so it isn't replacing the default weak interrupt handler that CubeMX provides. \$\endgroup\$
    – Devan
    Commented Jan 10, 2017 at 17:51
  • \$\begingroup\$ I just found the solution, and it is exactly what you said. Funny how I wasted half a day looking for a solution only to find it a few minutes after posting the question. \$\endgroup\$
    – John
    Commented Jan 10, 2017 at 17:52
  • \$\begingroup\$ This actually is a very well-known problem in embedded. It surprises me somewhat that appropriately chosen search terms didn't immediately give any of the dozens of Keil-Fora, TI-fora, StackOverflow, etc links I seem to get when I try. \$\endgroup\$
    – Asmyldof
    Commented Jan 10, 2017 at 18:02

1 Answer 1

11
\$\begingroup\$

I've been searching for a solution for half a day, only to find it a few minutes after I posted this question. The answer is given by this post:

Bug in Keil ARM compiler with interrupt handlers and C++?

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 } }

Or you can just declare it as

extern "C" void SysTick_Handler(void);

So you don't have to wrap it.

\$\endgroup\$

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