mathertel / DMXSerial

An Arduino library for sending and receiving DMX packets.
BSD 3-Clause "New" or "Revised" License
320 stars 76 forks source link

megaavr PlatformsIO compability #43

Closed jonolt closed 3 years ago

jonolt commented 4 years ago

compiling this simple working example for the Arduino Nano Every

#include <Arduino.h>

#include <DMXSerial.h>

void setup() {
  // put your setup code here, to run once:
  // Serial.begin(9600);
  DMXSerial.init(DMXController, 4);
}

void loop() {
  // put your main code here, to run repeatedly:
  // if(Serial.available()){}
}

works flawless with the Android IDE but fails at PlatformIO at linking:

Processing nano_every (platform: atmelmegaavr; board: nano_every; framework: arduino)
---------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelmegaavr/nano_every.html
PLATFORM: Atmel megaAVR 1.0.0 > Arduino Nano Every
HARDWARE: ATMEGA4809 16MHz, 6KB RAM, 47.50KB Flash
PACKAGES: 
 - framework-arduino-megaavr 1.8.6 
 - toolchain-atmelavr 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 9 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <DMXSerial> 1.5.0
Building in release mode
...
Compiling .pio/build/nano_every/src/main.cpp.o
Compiling .pio/build/nano_every/lib001/DMXSerial_ID912/DMXSerial.cpp.o
Archiving .pio/build/nano_every/lib001/libDMXSerial_ID912.a
Indexing .pio/build/nano_every/lib001/libDMXSerial_ID912.a
Linking .pio/build/nano_every/firmware.elf
DMXSerial.cpp.o (symbol from plugin): In function `_DMX_init()':
(.text+0x0): multiple definition of `__vector_26'
.pio/build/nano_every/FrameworkArduino/UART1.cpp.o (symbol from plugin):(.text+0x0): first defined here
DMXSerial.cpp.o (symbol from plugin): In function `_DMX_init()':
(.text+0x0): multiple definition of `__vector_27'
.pio/build/nano_every/FrameworkArduino/UART1.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
*** [.pio/build/nano_every/firmware.elf] Error 1

First the framework version was 1.8.5 (not 1.8.6) which caused some namespace errors which was fixed with an update of the platformio library, that I have requested. Now they should be identical and I'm getting above error.

I have read the Issues #42, #33 and #14, but I think I got another problem since I'm using no other library (planning to use Serial, which uses UART0, not UART1) and I'm pretty sure I got the right board selected.

I don't know C/C++ and avr-gcc well enough to solve this one alone, though I know the problem lies somewhere in the UART access.

I will/can also try to solve this myself if you point me in the right direction. Maybe the differences in the compiler option are of help (see below).

comparison of compiler options of arduino and platformio verbose output

sorted alphabeticaly, with empty cells for "missing" parameters Arduino IDE PlatformsIO
-c -c
-CC
-DARDUINO_ARCH_MEGAAVR -DARDUINO_ARCH_MEGAAVR
-DARDUINO_AVR_NANO_EVERY -DARDUINO_AVR_NANO_EVERY
-DARDUINO=10812 -DARDUINO=10808
-DAVR_NANO_4809_328MODE -DAVR_NANO_4809_328MODE
-DF_CPU=16000000L -DF_CPU=16000000L
-DMILLIS_USE_TIMERB3 -DMILLIS_USE_TIMERB3
-DNO_EXTERNAL_I2C_PULLUP -DNO_EXTERNAL_I2C_PULLUP
-DPLATFORMIO=40304
-DUSB_MANUFACTURER=\"Arduino\"
-DUSB_PID=0x0058 "-DUSB_PRODUCT=\"Arduino Nano Every\""
-DUSB_VID=0x2341
-E
-fdata-sections -fdata-sections
-ffunction-sections -ffunction-sections
-flto -flto
-fno-exceptions -fno-exceptions
-fno-threadsafe-statics -fno-threadsafe-statics
-fpermissive -fpermissive
-g
-I/home/johannes/Arduino/libraries/DMXSerial/src -I/home/johannes/.platformio/lib/DMXSerial_ID912/src
-I/home/johannes/.arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino -I/home/johannes/.platformio/packages/framework-arduino-megaavr/cores/arduino
-I/home/johannes/.arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/deprecated -I/home/johannes/.platformio/packages/framework-arduino-megaavr/cores/arduino/api/deprecated
-I/home/johannes/.arduino15/packages/arduino/hardware/megaavr/1.8.6/variants/nona4809 -I/home/johannes/.platformio/packages/framework-arduino-megaavr/variants/nona4809
-mmcu=atmega4809 -mmcu=atmega4809
-o /dev/null -o .pio/build/nano_every/lib001/DMXSerial_ID912/DMXSerial.cpp.o
-Os -Os
-std=gnu++11 -std=gnu++11
-w -w -w
-Wno-error=narrowing -Wno-error=narrowing
-x c++
/home/johannes/Arduino/libraries/DMXSerial/src/DMXSerial.cpp /home/johannes/.platformio/lib/DMXSerial_ID912/src/DMXSerial.cpp
/home/johannes/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ avr-g++
mathertel commented 4 years ago

Hi Johannes, These 2 vectors are the interrupt routines for the Serial UART1. I also see no special thing pointing to something else using UART1. I don't use the -DAVR_NANO_4809_328MODE option but it compiles as well on Arduino without reporting conflicts. This is odd. I wish you find "something".

jonolt commented 3 years ago

Identified Problem

After not getting any different results by playing with the compiler flags, i checked the files being linked. PlatformIO does -at least with my (default) settings- compile all files from the arduino core and tries to link them all with my other source files, even when I don't use them

Building in release mode
avr-g++ -o .pio/build/nano_every/firmware.elf -Os -flto -mmcu=atmega4809 -Wl,--gc-sections -Wl,--section-start=.text=0x0 -fuse-linker-plugin .pio/build/nano_every/FrameworkArduinoVariant/variant.c.o .pio/build/nano_every/FrameworkArduino/CDC.cpp.o .pio/build/nano_every/FrameworkArduino/NANO_compat.cpp.o .pio/build/nano_every/FrameworkArduino/Tone.cpp.o .pio/build/nano_every/FrameworkArduino/UART.cpp.o .pio/build/nano_every/FrameworkArduino/UART0.cpp.o .pio/build/nano_every/FrameworkArduino/UART1.cpp.o .pio/build/nano_every/FrameworkArduino/UART2.cpp.o .pio/build/nano_every/FrameworkArduino/UART3.cpp.o .pio/build/nano_every/FrameworkArduino/UNO_compat.cpp.o .pio/build/nano_every/FrameworkArduino/USBCore.cpp.o .pio/build/nano_every/FrameworkArduino/WInterrupts.cpp.o .pio/build/nano_every/FrameworkArduino/WMath.cpp.o .pio/build/nano_every/FrameworkArduino/abi.cpp.o .pio/build/nano_every/FrameworkArduino/api/Common.cpp.o .pio/build/nano_every/FrameworkArduino/api/IPAddress.cpp.o .pio/build/nano_every/FrameworkArduino/api/PluggableUSB.cpp.o .pio/build/nano_every/FrameworkArduino/api/Print.cpp.o .pio/build/nano_every/FrameworkArduino/api/Stream.cpp.o .pio/build/nano_every/FrameworkArduino/api/String.cpp.o .pio/build/nano_every/FrameworkArduino/hooks.c.o .pio/build/nano_every/FrameworkArduino/main.cpp.o .pio/build/nano_every/FrameworkArduino/new.cpp.o .pio/build/nano_every/FrameworkArduino/wiring.c.o .pio/build/nano_every/FrameworkArduino/wiring_analog.c.o .pio/build/nano_every/FrameworkArduino/wiring_digital.c.o .pio/build/nano_every/FrameworkArduino/wiring_pulse.S.o .pio/build/nano_every/FrameworkArduino/wiring_pulse.c.o .pio/build/nano_every/FrameworkArduino/wiring_shift.c.o .pio/build/nano_every/src/main.cpp.o -L.pio/build/nano_every -Wl,--start-group .pio/build/nano_every/lib4b0/libDMXSerial.a -lm -Wl,--end-group
DMXSerial.cpp.o (symbol from plugin): In function `_DMX_init()':
(.text+0x0): multiple definition of `__vector_26'
.pio/build/nano_every/FrameworkArduino/UART1.cpp.o (symbol from plugin):(.text+0x0): first defined here
DMXSerial.cpp.o (symbol from plugin): In function `_DMX_init()':
(.text+0x0): multiple definition of `__vector_27'
.pio/build/nano_every/FrameworkArduino/UART1.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
*** [.pio/build/nano_every/firmware.elf] Error 1

while the ArduinoIDE is only linking the neccesarry files

Linking everything together...
/home/johannes/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-gcc -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -Wl,--section-start=.text=0x0 -mmcu=atmega4809 -o /tmp/arduino_build_176197/sketch_jul20a.ino.elf /tmp/arduino_build_176197/sketch/sketch_jul20a.ino.cpp.o /tmp/arduino_build_176197/libraries/DMXSerial/DMXSerial.cpp.o /tmp/arduino_build_176197/core/variant.c.o /tmp/arduino_build_176197/../arduino_cache_832754/core/core_arduino_megaavr_nona4809_mode_off_c1f597cf3dd931fc8d6bf7075b294c68.a -L/tmp/arduino_build_176197 -lm
/home/johannes/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O binary -R .eeprom /tmp/arduino_build_176197/sketch_jul20a.ino.elf /tmp/arduino_build_176197/sketch_jul20a.ino.bin
/home/johannes/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /tmp/arduino_build_176197/sketch_jul20a.ino.elf /tmp/arduino_build_176197/sketch_jul20a.ino.eep
/home/johannes/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O ihex -R .eeprom /tmp/arduino_build_176197/sketch_jul20a.ino.elf /tmp/arduino_build_176197/sketch_jul20a.ino.hex
Using library DMXSerial at version 1.5.2 in folder: /home/johannes/Arduino/libraries/DMXSerial 
/home/johannes/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-size -A /tmp/arduino_build_176197/sketch_jul20a.ino.elf
Sketch uses 2678 bytes (5%) of program storage space. Maximum is 49152 bytes.
Global variables use 560 bytes (9%) of dynamic memory, leaving 5584 bytes for local variables. Maximum is 6144 bytes.

(adding the UART1.cpp.o to the linking command of the ArduinoIDE will raise the same error).

So it is no real bug since you usually shouldn't use Serial1 when using DMX Serial any ways. Now I only have to find out, how to solve this in PlatformIO. I will write an update when I have found a solution, until then I symlinked my source files into a ArduinoIDE folder strucure (and enable use external editor in the options) for my cross platform tests.

mathertel commented 3 years ago

Thanks for the investigation.