1

I'm trying to use SysTick_Handler in a project which uses the mbed libraries and RTOS, however on compilation, the following error is returned: Error: Symbol SysTick_Handler multiply defined (by ../../build/mbed-os/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.LPC1768.o and ../../build/main.LPC1768.o).

This leads me to believe that SysTick_Handler is used somewhere in the mbed library. Does this mean I cannot use it, and I have to resort to using the LPC1768s Timers?

The other definition appears to be in irq_cm3.0

Boiled down version of code:

#include "mbed.h"
#include "EthernetInterface.h"


extern "C" void SysTick_Handler()
{


}

// Socket demo
int main()
{
SysTick_Config(SystemCoreClock / 1000); 

}
19172281
  • 685
  • 1
  • 9
  • 24
  • 2
    The compiler should tell you **exactly** where the two definitions occur...in which files. Look at the entire error message. You also need to show us your code. – Elliot Alderson Apr 04 '19 at 18:54
  • It seems likely to me that the mbed libraries will provide you with a callback/hook to allow you to link your own handler to the existing one. – brhans Apr 04 '19 at 18:58
  • @ElliotAlderson, please see updated question. – 19172281 Apr 04 '19 at 19:02
  • Looks like you need to either put your code in the existing function, call your code from the existing function, or remove that and substitute your own. Any of these may break compatibility with future MBED versions so you'll need to do something like use a version control system to keep careful track of what changes you make on top of the upstream. That said, it's not entirely convincing that you have found the code in use; one would expect a counter to be incremented and likely some pumping of the RTOS scheduler, unless it is operating off a different timer. – Chris Stratton Apr 04 '19 at 19:08
  • 1
    For the record, it is the *linker* which would notice multiple definition, not the compiler. – Chris Stratton Apr 04 '19 at 19:09
  • How would I go about finding it? And if I were to remove it, what risks are there? – 19172281 Apr 04 '19 at 19:13
  • In my experience, the default handlers are "weakly" defined by the default include files. A weak definition allows the function to be redefined later, as you have done. However, I am most familiar with gcc and bare-metal CMSIS so I can't speak for the mbed environment. – Elliot Alderson Apr 04 '19 at 20:03
  • @ChrisStratton Yes, thanks for the clarification. I was thinking of the common mistake of defining a function in a header file instead of merely declaring it, which can be caught by the compiler. – Elliot Alderson Apr 04 '19 at 20:05
  • @ElliotAlderson, except in this case it hasn't allowed me to redefine it, without throwing an error – 19172281 Apr 04 '19 at 20:05
  • @19172281 - you need to `edit` the actual build error message into your question – Chris Stratton Apr 04 '19 at 20:06
  • @ChrisStratton, Done :) – 19172281 Apr 04 '19 at 20:08
  • So you need to find irq_cm3.h and/or irq_cm3.c and examine those files. There should be some helpful comments in them. – Elliot Alderson Apr 04 '19 at 20:15
  • I think the chances that SysTick_Handler() are in use by the RTOS are extremely high. After all, the SysTick timer was included in the ARM Cortex core itself (rather than as 3rd-party peripheral) for the explicit use by RTOSs in order to improve RTOS compatibility across all ARM Cortex products. I am not sure but I suspect it is bad practice to modify the SysTick_Handler in the presence of an RTOS. If you wanted to use the SysTick timer for something while running the RTOS, I suspect you're actually supposed use the RTOS API and if it doesn't let you then you're not meant to use it yourself. – DKNguyen Apr 04 '19 at 20:33
  • @Toor, so do you think using the LPC1768's Timer Interrupt is the way to go? Especially if I don't want to use Ticker – 19172281 Apr 04 '19 at 20:42
  • If the RTOS is running off the SysTick timer (and I'm 90% sure it is, maybe even 99% sure), you really don't want to muck with that. But my understanding is that when an RTOS is present, you access interrupts through the RTOS API since it oversees and manages everything. Some RTOSs allow direct hardware access for interrupts that are extremely critical so that the RTOS's own processes don't get in the way, but all lower priority interrupts are still managed through the RTOS. So I would use the LPC1768 regular timers, but if I needed those timer interrupts, I would check RTOS API first. – DKNguyen Apr 04 '19 at 20:50
  • @Toor, am I safe to use Timer0 without it interfering with the RTOS? – 19172281 Apr 04 '19 at 21:31
  • Look at your RTOS manual. – DKNguyen Apr 04 '19 at 21:32

1 Answers1

1

As said in the comments, the SysTick timer is indeed in use by the RTOS and you should not muck with this. Use the Ticker class if you need to tick regularly, it will drive the underlying high-precision timer on the platform (and is portable code). An additional benefit is that multiple Tickers can be created and they'll all use the same hardware timer.

void tick() {
    // do things, note that this runs in an ISR
}

Ticker t;
t.attach_us(&tick, 1000 /* 1ms. */);
Jan Jongboom
  • 336
  • 1
  • 7
  • Can I use Timer0, if I need lower level control? – 19172281 Apr 05 '19 at 12:23
  • Sure, but would you actually need it? You can set which timer source is used for the Ticker [yourself](https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_NXP/TARGET_LPC176X/us_ticker.c#L31), and then Mbed OS will do all the bookkeeping. – Jan Jongboom Apr 07 '19 at 08:39