Compile errors while attempting to port Arduino library

Hey everyone,

I’m attempting to port an Arduino library but am running into the following compile error using GNU Autotool chain on mac.

Here is the error:

Invoking: ARM GCC C++ Linker
mkdir -p ../../../build/target/user-part/platform-6-m/
arm-none-eabi-g++ -DSTM32_DEVICE -DSTM32F2XX -DPLATFORM_THREADING=1 -DPLATFORM_ID=6 -DPLATFORM_NAME=photon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD006 -DUSBD_PID_CDC=0xC006 -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -DINCLUDE_PLATFORM=1 -fno-builtin -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=0.6.2 -DRELEASE_BUILD -Werror -I./inc -I../../../user/inc -I../../../dynalib/inc -I../../../services/inc -I../../../hal/inc -I../../../hal/shared -I../../../hal/src/photon -I../../../hal/src/stm32f2xx -I../../../hal/src/stm32 -I../../../hal/src/photon/api -I../../../system/inc -I../../../rt-dynalib/inc -I../../../wiring/inc -I../../../modules/photon/system-part1/inc -I../../../modules/shared/stm32f2xx/inc -I../../../platform/shared/inc -I../../../platform/MCU/STM32F2xx/CMSIS/Include -I../../../platform/MCU/STM32F2xx/CMSIS/Device/ST/Include -I../../../platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc -I../../../platform/MCU/shared/STM32/inc -I../../../platform/MCU/STM32F2xx/STM32_StdPeriph_Driver/inc -I../../../platform/MCU/STM32F2xx/STM32_USB_Device_Driver/inc -I../../../platform/MCU/STM32F2xx/STM32_USB_Host_Driver/inc -I../../../platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc -I. -MD -MP -MF ../../../build/target/user-part/platform-6-m/helium.elf.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -Wundef -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 -DUSER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -DMODULAR_FIRMWARE=1 -DMODULE_VERSION=4 -DMODULE_FUNCTION=5 -DMODULE_INDEX=1 -DMODULE_DEPENDENCY=4,2,108 -D_WINSOCK_H -D_GNU_SOURCE ../../../build/target/user-part/platform-6-m/src/module_info.o ../../../build/target/user-part/platform-6-m/src/user_export.o ../../../build/target/user-part/platform-6-m/src/user_module.o ../../../build/target/user-part/platform-6-m/src/newlib_stubs.o  --output ../../../build/target/user-part/platform-6-m/helium.elf -Wl,--whole-archive ../../../hal/src/photon/lib/STM32F2xx_Peripheral_Libraries.a -Wl,--no-whole-archive -nostartfiles -Xlinker --gc-sections -L../../../build/arm/linker/stm32f2xx  -L../../../build/target/user/platform-6-m/applications/helium/ -L../../../build/target/services-dynalib/arm/ -L../../../build/target/hal-dynalib/platform-6-m/ -L../../../build/target/system-dynalib/platform-6-m/ -L../../../build/target/rt-dynalib/platform-6-m/ -L../../../build/target/wiring/platform-6-m/ -L../../../build/target/communication-dynalib/platform-6-m/ -L../../../build/target/platform/platform-6-m/ -L../../../build/target/wiring_globals/platform-6-m/ -L../../../hal/src/photon/lib/ -L../../../build/arm/linker -Wl,--whole-archive -luser -lhal-dynalib -lservices-dynalib -lsystem-dynalib -lrt-dynalib -lwiring -lcommunication-dynalib -lplatform -lwiring_globals -Wl,--no-whole-archive -lnosys --specs=nano.specs -L../../../modules/photon/system-part2 -L../../../modules/photon/system-part1 -L. -T./linker.ld -Wl,--defsym,USER_FIRMWARE_IMAGE_SIZE=0x20000 -Wl,--defsym,USER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -Wl,-Map,../../../build/target/user-part/platform-6-m/helium.map
/usr/local/Cellar/gcc-arm-none-eabi-49/20150609/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/libg_nano.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/usr/local/Cellar/gcc-arm-none-eabi-49/20150609/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/libg_nano.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/usr/local/Cellar/gcc-arm-none-eabi-49/20150609/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/libg_nano.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/usr/local/Cellar/gcc-arm-none-eabi-49/20150609/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/libg_nano.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/usr/local/Cellar/gcc-arm-none-eabi-49/20150609/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/libg_nano.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
/usr/local/Cellar/gcc-arm-none-eabi-49/20150609/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/libg_nano.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
collect2: error: ld returned 1 exit status
make[1]: *** [../../../build/target/user-part/platform-6-m/helium.elf] Error 1
make: *** [modules/photon/user-part] Error 2

This error is being created by this block of code(I know because it compiles fine with it commented out:

int
helium_connect(struct helium_ctx * ctx,
               struct connection * connection,
               int32_t             retries)
{
    ctx->txn.cmd._tag         = cmd_tag_connect;
    ctx->txn.cmd.connect._tag = cmd_connect_tag_req;

    if (NULL != connection)
    {
        ctx->txn.cmd.connect.req._tag  = req_connect_tag_quick;
        ctx->txn.cmd.connect.req.quick = *connection;
    }
    else
    {
        ctx->txn.cmd.connect.req._tag = req_connect_tag_cold;
    }

    enum send_command_status status = send_command(ctx);
    if (send_command_OK != status)
    {
        return helium_connect_ERR_COMMUNICATION;
    }

    while (retries-- > 0)
    {
        enum helium_connected_status connected_status = helium_connected(ctx);
        switch (connected_status)
        {
        case helium_connected_CONNECTED:
            return helium_connect_CONNECTED;
        case helium_connected_NOT_CONNECTED:
            if (retries > 0)
            {
                helium_wait_us(ctx->param, HELIUM_POLL_WAIT_US);
            }
            break;
        case helium_connected_ERR_COMMUNICATION:
            return helium_connect_ERR_COMMUNICATION;
        }
    }

    if (retries <= 0)
    {
        return helium_connect_NOT_CONNECTED;
    }

    return helium_connect_ERR_COMMUNICATION;
}

Not sure if that is enough info or not. I believe this stackoverflow post may be relevant but not sure how to implement the suggested solution:

You will need trace down into the called functions of the library too to find the offending C/C++ stdio call.

IE:

  • send_command
  • helium_connected(ctx)
  • helium_wait_us

Please post a link to the library code.

1 Like

I’ll keep digging. Here is the library:

1 Like

There are some printf’s in the code that could be getting compiled depending on how you set the #define settings:

2 Likes

which file are you looking at?

HE_DEBUG_ATOM is not defined so printf’s there should not be called.

Hi @IOTrav

The link I put in above is a search link, so click it. To answer your question:

src/helium-client/helium-client.c
src/helium-client/cauterize/cauterize.h

src/Helium.cpp

has a Stream object read/write which might be harmless, but you never know.

bool
helium_serial_readable(void * param)
{
    Stream * stream = (Stream *)param;
    return stream->available() > 0;
}

bool
helium_serial_getc(void * param, uint8_t * ch)
{
    Stream * stream = (Stream *)param;
    *ch             = stream->read();
    return *ch != -1;
}

bool
helium_serial_putc(void * param, uint8_t ch)
{
    Stream * stream = (Stream *)param;
    return stream->write(ch) == 1;
}

These looked like regular Arduino Stream class overloads to me, but you never know.

1 Like

@IOTrav - I downloaded a copy and subjecting it to two separate tool chains and getting nowhere. Probably needs another cup of coffee. :coffee:

Are you compiling it against one of the examples? or do you have another sketch? Please post that if possible.

The library by itself will compile, but none of the functions are called. It is when the main program begins using the functions fun things start to happen.

2 Likes

@cermak and @bko

Here is my port of the library as it stands:

Most of what I have done is to replace hardware serial with UartSerial and I changed uint8_t variables in the original library to unsigned chars. Nothing much beyond that.

1 Like

It appears to be something in send_command in the helium-client.c If I comment out the whole function except for the last line(return send_command_ok) everything compiles correctly.

Getting it narrowed down I guess…

Well, that calls CAUT_ASSERT which looks to me like it still calls printf. This is the second file in my original post about printf’s.

2 Likes

Right. That’s what I’m seeing. So what’s the fix for this? Just use Serial.printf to print to the serial log I guess? Would just need to include spark_wiring_usbserial.h then do search replace for printf -> serial.printf?

Just comment it out for now (carefully, it is in a macro). If you don’t fail the assertion it will never get called.

1 Like

Thanks @bko

Commented(very carefully :wink:)

#define CAUT_ASSERT(EXP) \
  do { \
    if (!(EXP)) { \
      /*printf("ASSERT FAIL on %s:%u\n\t" #EXP, __FILE__, __LINE__);*/ \
      exit(__LINE__); \
    } \
  } while(0)

Compile success

1 Like