PlatformIO Community

Error when building latest 3D printer firmware

Apologies if I’m not asking this in the right place.

I had been successfully building 3D printer firmware at the previous revision level. The latest version is failing with errors however, and I don’t know how to fix it.

This is the source code I can build just fine with no errors:

This is the latest version that throws errors when I try to build:

Here is the output when I attempt to build:

Executing task: C:\Users\teook\.platformio\penv\Scripts\platformio.exe run <

Processing reprap_rambo (platform: atmelavr; board: reprap_rambo; framework: arduino)

Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/reprap_rambo.html
PLATFORM: Atmel AVR 1.15.0 > RepRap RAMBo
HARDWARE: ATMEGA2560 16MHz, 8KB RAM, 252KB Flash
PACKAGES: toolchain-atmelavr 1.50400.190710 (5.4.0), framework-arduinoavr 4.1.2
Converting Firmware.ino
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 14 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Wire> 1.0
Compiling out\reprap_rambo\src\Firmware.ino.cpp.o
Linking out\reprap_rambo\firmware.elf
wiring.c.o (symbol from plugin): In function `__vector_23':
(.text+0x0): multiple definition of `__vector_23'
out\reprap_rambo\src\heatbed_pwm.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
*** [out\reprap_rambo\firmware.elf] Error 1

And here is my platformio.ini file:

[env:reprap_rambo]
monitor_speed = 115200
platform = atmelavr
board = reprap_rambo
framework = arduino
build_flags = -w -Os -Wl,-u,vfprintf -lprintf_flt -lm -Wl,--gc-sections

[platformio]
src_dir = Firmware
build_dir = out

Any help figuring out why the new version will not build is appreciated.

Thanks.

First google result for multiple definition of '__vector_23':

Looking at the code that doesn’t build, there is the ISR

This file is non-existant for your working 3.7.2 version, explaining why it works.

This issue with the new version is also already referenced in the project you linked to

With the solution

Which points to this Arduino core / board definition

https://raw.githubusercontent.com/DRracer/Arduino_Boards/master/IDE_Board_Manager/package_prusa3d_index.json

Their core’s wiring.c has the “fix” which is surrounding the TIMER0 vector used by millis() with #ifdef 0. Read the comment for explanation.

So what you need to do is import the same core and variant definition as this project commands you to do. That is,

board_build.core = rambo

(board_build.variant must not be altered because it already is rambo)

(this is all documented in the documentation and board’s JSON file)

2 Likes

Thank you for the extremely detailed reply. I deserved the admonishment to google first…

It worked! And just for the record, even if I had googled and found the existing issue threads in the project I wouldn’t have know how to force PIO to play nice with the altered board and core definitions. So thanks for spelling it all out for me.

Thanks a million!

2 Likes

Great!

Just as a followup, the problem was actually reported multiple times in the repo (https://github.com/wavexx/Prusa-Firmware/issues/5, https://github.com/prusa3d/Prusa-Firmware/issues/2027) and a PR to PIO’s platform-atmelavr and related repo has been accepted (https://github.com/platformio/platformio-pkg-framework-arduinoavr/pull/22, https://github.com/platformio/platform-atmelavr/pull/163/files), so after a new release you can update your PlatformIO platforms (pio platform update) and you will just need to use board = prusa_rambo (new board’s file at the moment of writing). The correct Arduino core is then built into framework-arduinoavr already.

1 Like

Ah, I’m glad people who actually know what they are doing are working this issue.

I will qualify my earlier “it works!” statement however by noting that the UI is funky with firmwares built with this method. The printer functions properly, but the LCD screen UI is not filling in with all the information it normally would.

So, we are getting closer but not quite there yet.

Thanks.

Hm interesting info because the exact same problem is described in the PR… What exact config are you having on your build and what hardware LCD device do you have?

1 Like

I’m building with this platformio.ini:

[env:reprap_rambo]
monitor_speed = 115200
platform = atmelavr
board = reprap_rambo
framework = arduino
build_flags = -w -Os -Wl,-u,vfprintf -lprintf_flt -lm -Wl,--gc-sections

;required now that prusa have modified rambo
board_build.core = rambo

[platformio]
src_dir = Firmware
build_dir = out

Here is a drop in replacement for the standard LCD. Unfortunately it does not list any of the specs. I think it’s just a standard 4 line interfacing with I2C.

And this might be releated? PIO is flagging several problems in the LCD code but we are in way over my head at this point already…

lcd.cpp:

ultralcd.cpp

First message indicates a problem with the return value of the function, second one is more interesting because it tells you that there’s an overflow for to-be-fitted data compared to the available space. This commit seems to address it. Do you have a version of the firmware where these changes are applied?

Also can you show a comparison of how the LCD looks like correctly with Arduino IDE with PIO?

1 Like

I merged that commit to 3.8.0 and it said “already up to date”.

Here is 3.8.0 built with PIO:
Google Photos

And here it is built in Ubuntu with the prusa-supplied build.sh:
Google Photos

So it seems it is compiling for a MK3S when MK3 is actually correct. Which strongly hints at a wrong variant being used. Which of these files is the correct one for your device? https://github.com/prusa3d/Prusa-Firmware/tree/4c22ec234f153851064229eeea10542a57beb7b9/Firmware/variants. Well yeah probably MK3 silly question. Hold on a second.

Seems like we don’t copy the right variant .h file as the script does

if [ ! -f "$SCRIPT_PATH/Firmware/Configuration_prusa.h" ]; then
    cp $SCRIPT_PATH/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h $SCRIPT_PATH/Firmware/Configuration_prusa.h || exit 8
fi

Can you replace the Configuration_prusa.h file found in the firmware prject with the .h file for the MK3 and recompile?

1 Like

The LCD should work regardless of the printer variant.

The fact that it’s compiling for MK3 in Ubuntu is I think a different issue and is probably user error. I have the MK3S variant file selected in both cases. I just haven’t figured out why the build.sh seems to ignore it (never used it until today while trying to troubleshoot building in PIO).

I can flash the official firmware for either MK3 or MK3S and the screen displays correctly in both cases.

Should work or does work is important here. Can you compile the MK3S variant with the build.sh (overwriting Firmware/Configuration_prusa.h with the config file for the MK3S and then executing build.sh should be enough) so that we can get a picture on what the MK3S firmware is supposed to look like correctly?

1 Like

So I got a tip from someone on discord:

This is a regression issue with the extended undergoing optimizations at the PR Marlin.
I've reported it and they acknowledged it, but they haven't fixed it yet.
If I understand correctly, it depends on the optimizations that the compiler chooses.

To fix this do the following changes:
At the lcd.cpp, at line ~192 change the whole function:
static void lcd_putchar(char c, FILE *)
with:
static int lcd_putchar(char c, FILE *)
{
    lcd_write(c);
    return 0;
}

and at the lcd.h, the definition:
extern void lcd_putchar(char c, FILE *stream);
with:
extern int lcd_putchar(char c, FILE *stream);

I made the suggested edits, and the UI now displays correctly when building with platformIO.

Oh well this is then just as I said

But I didn’t think it would be that severe. In hindsight, if the compiler expects an int as the return value it will pop a value from the stack after calling the function, however corrupting the stack if there is no such value pushed by the function. Or just undefined behavior. Case closed then I guess.

2 Likes

Appreciate all your help, maxgerhardt. I learned a thing or two. :+1:

Could you try the next configuration?

[env:reprap_rambo]
monitor_speed = 115200
platform = https://github.com/platformio/platform-atmelavr.git
board = reprap_rambo
framework = arduino
build_flags = -w -Os -Wl,-u,vfprintf -lprintf_flt -lm -Wl,--gc-sections

lib_archive = false

[platformio]
src_dir = Firmware
build_dir = out

reprap_rambo board will use the wrong core. The ‘arduino’ core defines the TIMER0 and it’s redefined in the Prusa Firmware code; so build error. That’s why I pushed a PR with a new ‘rambo’ core and new ‘prusa_rambo’ board for building Prusa Firmware.

1 Like

Aggreed, must be board = prusa_rambo, see https://github.com/platformio/platform-atmelavr/blob/develop/boards/prusa_rambo.json#

1 Like

Why do we need this https://github.com/platformio/platform-atmelavr/blob/develop/boards/reprap_rambo.json ? Maybe, just continue using this board and change core to rambo?

There is a special change in the wiring.c file linked to the fact that the Prusa firmware has its own TIMER0 implementation. And what about other rambo boards based on reprap that still needed the TIMER0 ?