HeliOS icon indicating copy to clipboard operation
HeliOS copied to clipboard

Linking problem with multiple files and HeliOS

Open paju2024 opened this issue 1 year ago • 2 comments

Encountered a strange problem which I cannot find a solution. Linking problem with multiple files that link fine when using FreeRTOS but not with HeliOS.

Made a simple test to verify this issue as well.

What works:

  • single file where the whole code is
  • includes arduino.h and helios.h and few other includes.
  • compiling, linking, download and code runs properly

What does not work:

  • a dedicated local.h with prevention to include multiple times (#ifndef...) which contain arduino.h and helios.h
  • 2 source files, where the same code as in the working example is located in one file and in the 2nd file there's only one dummy task that does nothing + include of local.h
  • one additional include file (dummy.h) which includes local.h and declaration of the dummy task (extern) so that it can be found
  • main code is modified to include local.h and registration of dummy-task
  • compile fine, link fails

.pio/build/megaatmega2560/src/main.cpp.o (symbol from plugin): In function display': (.text+0x0): multiple definition of xByte2String(unsigned int, unsigned char*)' .pio/build/megaatmega2560/src/dummy.cpp.o (symbol from plugin):(.text+0x0): first defined here collect2: error: ld returned 1 exit status *** [.pio/build/megaatmega2560/firmware.elf] Error 1

I have been using this local.h approach for a long time successfully e.g. with FreeRTOS but for some reason HeliOS doesn't like this at all (or linker doesn't like with HeliOS).

local.h: `#ifndef local_h #define local_h

#include <Arduino.h> #include <HeliOS.h>

#endif `

dummy.h: `#include "local.h"

extern void TaskDummy(xTask task_, xTaskParm parm_);`

dummy.c: `#include "local.h"

void TaskDummy(xTask task_, xTaskParm parm_) { // nothing }`

main.c (beginning of the file): #include "local.h" #include <SPI.h> #include <Adafruit_GFX.h> #include <Arduino_ST7789_Fast.h> #include "dummy.h" There comes usual setup() and loop() functions. In setup tasks are registered etc.

2. What results, output, behavior are you expecting?

Expectation is that the code would link normally with HeliOS.

3. What version of HeliOS are you using?

heliosproj/HeliOS@^0.4.1

4. Provide the following details about your development environment and development board/microcontroller:

OS [Windows, macOS, Linux]: Linux

OS Version [Windows 10, Ventura, Ubuntu 22.04]: OpenSUSE Tumbleweed

IDE [Arduino IDE, PlatformIO, STM32CubeIDE, Keil]: PlatformIO

IDE Version: 1.85.2

Board/MCU Mfg [Arduino, PJRC, ST Micro]: Arduino MEGA 2560 Pro

5. Are you experiencing any compiler or linker errors? If so, copy and paste them here (please do not provide screenshots):

.pio/build/megaatmega2560/src/main.cpp.o (symbol from plugin): In function display': (.text+0x0): multiple definition of xByte2String(unsigned int, unsigned char*)' .pio/build/megaatmega2560/src/dummy.cpp.o (symbol from plugin):(.text+0x0): first defined here collect2: error: ld returned 1 exit status *** [.pio/build/megaatmega2560/firmware.elf] Error 1

7. Attach a copy of your source code file(s) so we may compile them if needed:

HeliOS_test.zip

paju2024 avatar Feb 16 '24 19:02 paju2024

The problem is in HeliOS.h header file. Moved below part to own cpp-file and no more linking issue.

`#ifdef REMOVE #ifdef __cplusplus

#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_STM32) || \
defined(ARDUINO_TEENSY_MICROMOD) || defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY36) || defined(ARDUINO_TEENSY35) || \
defined(ARDUINO_TEENSY31) || defined(ARDUINO_TEENSY32) || defined(ARDUINO_TEENSY30) || defined(ARDUINO_TEENSYLC)
  String xByte2String(xSize size_, xByte *bytes_);


  /* This is here to give Arduino users an easy way to convert from the
   * HeliOS byte (xByte) array which is NOT null terminated to a String. */
  String xByte2String(xSize size_, xByte *bytes_) {
    String str = "";
    xSize i = 0;
    char buf[size_ + 1];


    if(NOTNULLPTR(bytes_) && (zero < size_)) {
      for(i = 0; i < size_; i++) {
        buf[i] = (char) bytes_[i];
      }

      buf[size_] = '\0';
      str = String(buf);
    }

    return(str);
  }


#endif /* if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAM) ||
        * defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_ESP8266) ||
        * defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_TEENSY_MICROMOD) ||
        * defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) ||
        * defined(ARDUINO_TEENSY36) || defined(ARDUINO_TEENSY35) ||
        * defined(ARDUINO_TEENSY31) || defined(ARDUINO_TEENSY32) ||
        * defined(ARDUINO_TEENSY30) || defined(ARDUINO_TEENSYLC) */

#endif /* ifdef __cplusplus */ #endif `

paju2024 avatar Feb 16 '24 20:02 paju2024

Thank you for reporting the issue. Looking into it.

MannyPeterson avatar Feb 20 '24 18:02 MannyPeterson