0

I'm having a hard time linking a my code against an Atmel library.

My code uses the function GetTickCount() defined in an Atmel Library. My cpp file compiles ok but fails on linking. The library is present during linkage and actually been used by another C file in the process.

  • My file I2C_due.cpp calls the function GetTickCount().

  • The function GetTickCount() is present in the library libsam_sam3x8e_gcc_rel.a (from timetick.c). This is a pre-built file from Atmel.

  • The file wiring.c (from Arduino) is compiled with my file, has calls to GetTickCount() as well, but it is placed inside libFrameworkArduino.a before linking.

During linkage, the linker does not complain about calls to GetTickCount() from wiring.c, but do about my file. If I remove the lib libsam_sam3x8e_gcc_rel.a from linker command line, it of course complains about wiring.c calls as well. So I'm sure the lib is being used during link (and it is at the end of command line, so the linker parses my file first).

I'm wondering about two things:

  1. I'm calling a C function inside a C++ method.

  2. Something related to the new C visibility feature.

The GetTickCount() is defined inside timetick.c embedded in libsam_sam3x8e_gcc_rel.a:

extern uint32_t GetTickCount( void )
{
    return _dwTickCount ;
}

timetick.h:

extern uint32_t GetTickCount( void ) ;

Linker command line:

arm-none-eabi-g++ -o .pioenvs/due/firmware.elf -Os -mthumb -mcpu=cortex-m3 \
  -Wl,--gc-sections -Wl,--check-sections -Wl,--unresolved-symbols=report-all \
  -Wl,--warn-common -Wl,--warn-section-align -Wl,--entry=Reset_Handler -u _sbrk \
  -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit \
  -u kill -u _getpid -Wl,-T"flash.ld" (many objects).o \
  .pioenvs/due/src/Marlin/HAL/DUE/I2C_due.o (many objects).o -L(many lib dirs) \
  -Wl,--start-group .pioenvs/due/libFrameworkArduinoVariant.a \
  .pioenvs/due/libFrameworkArduino.a -lc -lgcc -lm -lsam_sam3x8e_gcc_rel \
  .pioenvs/due/lib/libWire.a .pioenvs/due/lib/libSPI.a -Wl,--end-group

And the error:

/home/alex/(longdir)/HAL/DUE/I2C_due.cpp:239: undefined reference to `GetTickCount()'

...

.pioenvs/(longdir)/HAL/DUE/I2C_due.o:/home/alex/(longdir)/HAL/DUE/I2C_due.cpp:344: more undefined references to `GetTickCount()' follow

Just a check in the lib:

$ nm -s libsam_sam3x8e_gcc_rel.a | grep GetTickCount
GetTickCount in timetick.o
00000001 T GetTickCount

Any hint on how can I get my file linked??

Cheers.

Alex.

Alex Borro
  • 13
  • 3

1 Answers1

1

Analyzing R.. comment, I figured out my mistake.

There is not allowed to place a call to C function inside a C++ function. That's the reason we use the extern "C" before the function declaration.

I had to create a .c and .h files and use the extern "C" in the .h.

teste.c:

uint32_t MiliS()
{
    return GetTickCount();
}

teste.h:

extern "C" uint32_t MiliS();

That way we can call MiliS() from a .cpp file and it will be a wrapper to GetTickCount()

Alex Borro
  • 13
  • 3