TL;DR A compilation fails with "multiple definitions" noted and a call like this
Code: Select all
extern "C" void TIM2_IRQHandler(void) __attribute__((weak));
extern "C" void TIM2_IRQHandler(void) {
The details:
I am working with a "Blue Pill" STM32F103C8T6 (per the stamp on the chip) with 3.3V to "VBAT" for the RTC and am trying to have it initialized with two clocks. One clock would be set to universal time (UTC) and the other to sidereal ("star") time.
In working with some code on the 'net and with an AI assist, I can get a clock initialized and it will survive a reset. Where I am having compilation trouble is in implementing an interrupt handler for the second clock. Specifically, I get this compilation error:
Code: Select all
Linking everything together...
"C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\STMicroelectronics\\tools\\xpack-arm-none-eabi-gcc\\14.2.1-1.1/bin/arm-none-eabi-gcc" -mcpu=cortex-m3 -mthumb -Os -DNDEBUG --specs=nano.specs -Wl,--defsym=LD_FLASH_OFFSET=0x0 -Wl,--defsym=LD_MAX_SIZE=65536 -Wl,--defsym=LD_MAX_DATA_SIZE=20480 -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common "-Wl,--default-script=C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\STMicroelectronics\\hardware\\stm32\\2.11.0\\variants\\STM32F1xx\\F103C8T_F103CB(T-U)/ldscript.ld" "-Wl,--script=C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\STMicroelectronics\\hardware\\stm32\\2.11.0\\system/ldscript.ld" "-Wl,-Map,C:\\Users\\User\\AppData\\Local\\arduino\\sketches\
<snip verbose output>
C:/Users/User/AppData/Local/Arduino15/packages/STMicroelectronics/tools/xpack-arm-none-eabi-gcc/14.2.1-1.1/bin/../lib/gcc/arm-none-eabi/14.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\User\AppData\Local\arduino\sketches\1D1AECCACB69967E535E120A0E791A7C\libraries\SrcWrapper\HardwareTimer.cpp.o: in function `TIM2_IRQHandler':
HardwareTimer.cpp:(.text.TIM2_IRQHandler+0x0): multiple definition of `TIM2_IRQHandler'; C:\Users\User\AppData\Local\arduino\sketches\1D1AECCACB69967E535E120A0E791A7C\sketch\STM32_SiderealClockpt12.ino.cpp.o:STM32_SiderealClockpt12.ino.cpp:(.text.TIM2_IRQHandler+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
Using library STM32duino RTC at version 1.8.0 in folder: C:\Users\User\Documents\Arduino\libraries\STM32duino_RTC
Using library SrcWrapper at version 1.0.1 in folder: C:\Users\User\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.11.0\libraries\SrcWrapper
Using library USBDevice at version 1.0.0 in folder: C:\Users\User\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.11.0\libraries\USBDevice
exit status 1
Compilation error: exit status 1
Code: Select all
#include <STM32RTC.h>
#include <rtc.h>
#include <math.h>
/*
* STM32 Internal RTC Sidereal Time Clock
* --------------------------------------
* - Uses STM32 internal RTC (via STM32RTC library)
* - Stores UTC internally
* - Uses TIM2 (1 MHz base) for sidereal-rate timekeeping
* - Provides getCurrentSiderealTime() in hours
*/
// ============================================================
// Hardware and constants
// ============================================================
STM32RTC& rtc = STM32RTC::getInstance();
#define SIDEREAL_TIMER TIM2
#define SIDEREAL_TIMER_IRQn TIM2_IRQn
#define SIDEREAL_TIMER_HANDLER TIM2_IRQHandler
// ============================================================
// Globals
// ============================================================
volatile uint32_t realtime_seconds = 0; // updated by ISR every second
bool sidereal_initialized = false;
// ============================================================
// TIM2 initialization
// ============================================================
extern "C" void SIDEREAL_TIMER_HANDLER(void);
void initializeSiderealTimer()
{
SIDEREAL_TIMER->CR1 &= ~TIM_CR1_CEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
// 72 MHz / (PSC+1) = 1 MHz
SIDEREAL_TIMER->PSC = 71;
SIDEREAL_TIMER->ARR = 1000000 - 1;
SIDEREAL_TIMER->CNT = 0;
SIDEREAL_TIMER->SR = 0;
SIDEREAL_TIMER->DIER |= TIM_DIER_UIE;
NVIC_SetPriority(SIDEREAL_TIMER_IRQn, 1);
NVIC_EnableIRQ(SIDEREAL_TIMER_IRQn);
realtime_seconds = 0;
SIDEREAL_TIMER->CR1 |= TIM_CR1_CEN;
sidereal_initialized = true;
Serial.println("TIM2 initialized for 1Hz ISR (1µs base).");
}
extern "C" void SIDEREAL_TIMER_HANDLER(void)
{
if (SIDEREAL_TIMER->SR & TIM_SR_UIF) {
SIDEREAL_TIMER->SR &= ~TIM_SR_UIF;
realtime_seconds++;
}
}
uint64_t getElapsedRealMicros() //uint64_t ????
{
uint32_t s1, s2, cnt;
do {
noInterrupts();
s1 = realtime_seconds;
cnt = SIDEREAL_TIMER->CNT;
s2 = realtime_seconds;
interrupts();
} while (s1 != s2);
return (uint64_t)s1 * 1000000ULL + (uint64_t)cnt;
}
void setup() {
}
void loop() {
}
Code: Select all
extern "C" void TIM2_IRQHandler(void) __attribute__((weak));
extern "C" void TIM2_IRQHandler(void) {
if (TIM2->SR & TIM_SR_UIF) {
TIM2->SR &= ~TIM_SR_UIF;
// Increment sidereal microseconds (adjusted for sidereal rate)
sidereal_micros += (uint32_t)(1000000.0 * SIDEREAL_RATIO);
}
}
The goal is to have the clocks initialized and running (with battery backup) such that future sketches uploaded have access to UTC and sidereal time without having to have the overhead of calculating the values.
If this should be posted to a different board, please advise. And thank you in advance for any help.
Regards,
mconsidine
PS I'm compiling this with Arduino IDE 2.3.6 on Windows 10. And this is my first post here so apologies in advance if I've stepped on a protocol