Linker issue about gettimeofday() on Teensy 4.0 with FreeRTOS

fralbo

Member
Hello,
I cannot build my code on Teensy 4.0 with core library 1.58.0-beta2

c:/users/utilisateur/appdata/local/arduino15/packages/teensy/tools/teensy-compile/11.3.1-beta1/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\Utilisateur\AppData\Local\Temp\arduino-sketch-4BE4F06CEFDDFAC044404B2337125028/..\arduino-core-cache\core_9fa68f27d5e81ef98338bbff089303f0.a(rtc.c.o): in function `_gettimeofday':
.......\teensy\hardware\avr\1.58.0-beta2\cores\teensy4/rtc.c:76: multiple definition of `_gettimeofday'; ....\arduino-sketch-4BE4F06CEFDDFAC044404B2337125028\libraries\freertos-teensy-master\portable\teensy_common.cpp.o:d:\Users\Utilisateur\OneDrive\Documents\Arduino\libraries\freertos-teensy-master\src\portable/teensy_common.cpp:412: first defined here
collect2.exe: error: ld returned 1 exit status

This is a new problem, I didn't get it before Teensy core library update.

My code uses:
Code:
    #include <Arduino.h>
    #include "arduino_freertos.h"
    #include <ICM_20948.h>
    #include <PWMServo.h>
    #include <SPI.h>
    #include <SD.h>
Any idea to fix it please?
 
Install the 1.57 again. Remember that the beta versions seek to improve some aspects, but also usually bring some errors, in this case with the most recent version of the GNU toolchain, comes with some pre-halloween scares
 
Install the 1.57 again. Remember that the beta versions seek to improve some aspects, but also usually bring some errors, in this case with the most recent version of the GNU toolchain, comes with some pre-halloween scares

Actually the issue isn't with the new toolchain. I believe the issue is related to the addition of a _gettimeofday function added to core via this: https://github.com/PaulStoffregen/cores/commit/50342d77de1b495ee359e78c12153bb6532a5727.

You should probably create an issue on the FreeRTOS github to let them know they need to update their library for the new core.
 
I think that the new toolchain must have something, since this function: _gettimeofday, was not defined in the previous GNU.

So I think that some libraries must have it enabled. Is it possible to bypass the use of that GNU toolchain function, to use the custom version of such a function, so that the compiler does not generate a duplicity error?


In my case this is the error with 1.58-beta2 (with the 1.57 runs fine):

Code:
c:/users/w11pc/desktop/arduino-1.8.19   xd xd/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\W11PC\AppData\Local\Temp\arduino_build_795882/..\arduino_cache_583586\core\core_bcca1fd6f87e4a2e726df32b2b3408ee.a(rtc.c.o): in function `_gettimeofday':
C:\Users\W11PC\Desktop\arduino-1.8.19   XD XD\hardware\teensy\avr\cores\teensy4/rtc.c:76: multiple definition of `_gettimeofday'; C:\Users\W11PC\AppData\Local\Temp\arduino_build_795882\sketch\00_T41_Frio_Servo1.ino.cpp.o:C:\Users\W11PC\Documents\Arduino\libraries\nmealib/nmea.h:22: first defined here
collect2.exe: error: ld returned 1 exit status

If I comment out the function in the nmea.h file, the compiler doesn't show the error with loader 1.58-beta2, but I get the error with loader 1.57

Code:
c:/arduino-1.8.19/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv7e-m/fpu/fpv5-d16\libc.a(lib_a-gettimeofdayr.o): In function `_gettimeofday_r':
gettimeofdayr.c:(.text._gettimeofday_r+0x10): undefined reference to `_gettimeofday'
collect2.exe: error: ld returned 1 exit status
 
I think that the new toolchain must have something, since this function: _gettimeofday, was not defined in the previous GNU.

So I think that some libraries must have it enabled. Is it possible to bypass the use of that GNU toolchain function, to use the custom version of such a function, so that the compiler does not generate a duplicity error?


In my case this is the error with 1.58-beta2 (with the 1.57 runs fine):

Code:
c:/users/w11pc/desktop/arduino-1.8.19   xd xd/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\W11PC\AppData\Local\Temp\arduino_build_795882/..\arduino_cache_583586\core\core_bcca1fd6f87e4a2e726df32b2b3408ee.a(rtc.c.o): in function `_gettimeofday':
C:\Users\W11PC\Desktop\arduino-1.8.19   XD XD\hardware\teensy\avr\cores\teensy4/rtc.c:76: multiple definition of `_gettimeofday'; C:\Users\W11PC\AppData\Local\Temp\arduino_build_795882\sketch\00_T41_Frio_Servo1.ino.cpp.o:C:\Users\W11PC\Documents\Arduino\libraries\nmealib/nmea.h:22: first defined here
collect2.exe: error: ld returned 1 exit status

If I comment out the function in the nmea.h file, the compiler doesn't show the error with loader 1.58-beta2, but I get the error with loader 1.57

Code:
c:/arduino-1.8.19/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv7e-m/fpu/fpv5-d16\libc.a(lib_a-gettimeofdayr.o): In function `_gettimeofday_r':
gettimeofdayr.c:(.text._gettimeofday_r+0x10): undefined reference to `_gettimeofday'
collect2.exe: error: ld returned 1 exit status

Not sure what nmea library you all are using so can't not give it a try.

But as a test you could always just comment out the gettimeofday function in the teensy 4 core file: rtc.c , and give it another try.
 
Install the 1.57 again. Remember that the beta versions seek to improve some aspects, but also usually bring some errors, in this case with the most recent version of the GNU toolchain, comes with some pre-halloween scares

As a quick test I commented out gettimeofday in the rtc.c in the teensy4 core and the Arduino-freeRtos blick sketch ran with out an issue, i.e., no errors using 1.57-beta2
 
There are a few different FreeRTOS ports. I'm guessing you used this one?

https://github.com/tsandmann/freertos-teensy

Looks like it has an implementation of _gettimeofday() in src/portable/teensy_common.cpp at line 419:

https://github.com/tsandmann/freert...91d569707/src/portable/teensy_common.cpp#L419

This will need to be removed or disabled for compatibility with Teensyduino 1.58, since we're now providing this function in Teensy's core library.

Cleanest way is probably something like this...

Code:
[B][COLOR="#FF0000"]#if TEENSYDUINO < 158[/COLOR][/B]
FLASHMEM int _gettimeofday(timeval* tv, void*) {
    const auto now_us { freertos::get_us() };
#if defined(__has_include) && __has_include("freertos_time.h")
    const auto off { free_rtos_std::wall_clock::get_offset() };
#else
    const timeval off { 0, 0 };
#endif
    const timeval now { static_cast<time_t>(now_us / 1'000'000UL), static_cast<suseconds_t>(now_us % 1'000'000UL) };

    timeradd(&off, &now, tv);
    return 0;
}
[B][COLOR="#FF0000"]#endif[/COLOR][/B]
 
There are a few different FreeRTOS ports. I'm guessing you used this one?

https://github.com/tsandmann/freertos-teensy

Looks like it has an implementation of _gettimeofday() in src/portable/teensy_common.cpp at line 419:

https://github.com/tsandmann/freert...91d569707/src/portable/teensy_common.cpp#L419

This will need to be removed or disabled for compatibility with Teensyduino 1.58, since we're now providing this function in Teensy's core library.

Cleanest way is probably something like this...

Code:
[B][COLOR="#FF0000"]#if TEENSYDUINO < 158[/COLOR][/B]
FLASHMEM int _gettimeofday(timeval* tv, void*) {
    const auto now_us { freertos::get_us() };
#if defined(__has_include) && __has_include("freertos_time.h")
    const auto off { free_rtos_std::wall_clock::get_offset() };
#else
    const timeval off { 0, 0 };
#endif
    const timeval now { static_cast<time_t>(now_us / 1'000'000UL), static_cast<suseconds_t>(now_us % 1'000'000UL) };

    timeradd(&off, &now, tv);
    return 0;
}
[B][COLOR="#FF0000"]#endif[/COLOR][/B]

Just tried it and compiles with out errors and runs the blink sketch in the freeRTOS library without a problem. T4.1 is blinking and:
Code:
Running FreeRTOS kernel V10.5.0. Built by gcc 11.3.1 20220712.
setup(): starting scheduler...
TICK
TOCK
TICK
TOCK
TICK ...

Be honest forgot that you could test for Teensduino version.
 
PR has been incorporated with the following comment from @tsandmann

Thank you for figuring this out :)
The drawback might be a reduced resolution for things that use gettimeofday() like std::chrono or std::thread. But I think it's fine as a workaround, at least as long as Teensyduino 1.58 is still beta.
 
Back
Top