嵌入式C / C ++:现有符号

时间:2017-11-18 22:30:58

标签: c++ c linker embedded

我很难将我的代码链接到Atmel库。

我的代码使用Atmel库中定义的函数 GetTickCount()。我的cpp文件编译好,但链接失败。该库在链接期间存在,并且实际上已被该过程中的另一个C文件使用。

  • 我的文件 I2C_due.cpp 调用函数 GetTickCount()

  • 函数 GetTickCount()出现在库 libsam_sam3x8e_gcc_rel.a (来自 timetick.c )中。这是Atmel的预建文件。

  • 文件 wiring.c (来自Arduino)是用我的文件编译的,也调用 GetTickCount(),但它放在< strong> libFrameworkArduino.a 在链接之前。

在链接期间,链接器不会抱怨从 wiring.c 调用 GetTickCount(),而是关注我的文件。如果我从链接器命令行中删除lib libsam_sam3x8e_gcc_rel.a ,它当然也会抱怨 wiring.c 调用。所以我确定在链接期间使用了lib(它位于命令行的末尾,所以链接器首先解析我的文件)。

我想知道两件事:

  1. 我在C ++方法中调用C函数。

  2. 与新C可见性功能相关的内容。

  3. GetTickCount()是在 libsam_sam3x8e_gcc_rel.a 中嵌入的 timetick.c 中定义的:

    extern uint32_t GetTickCount( void )
    {
        return _dwTickCount ;
    }
    

    timetick.h

    extern uint32_t GetTickCount( void ) ;
    

    链接器命令行:

    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
    

    错误:

    /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
    

    只需检查一下lib:

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

    有关如何将文件链接起来的任何提示?

    干杯。

    亚历。

1 个答案:

答案 0 :(得分:1)

分析R ..评论,我弄清楚了我的错误。

不允许在C ++函数中调用C函数。 这就是我们在函数声明之前使用 extern“C”的原因。

我必须创建一个.c和.h文件,然后在.h中使用 extern“C”

<强> teste.c

uint32_t MiliS()
{
    return GetTickCount();
}

<强> teste.h

extern "C" uint32_t MiliS();

这样我们就可以从.cpp文件调用 MiliS(),它将成为 GetTickCount()

的包装器