Skip to content

String class not usable (no malloc) #5

Open
@maxgerhardt

Description

@maxgerhardt

The Arduino String class uses malloc, free and realloc to dynamically allocate memory for the strings. However, the core doesn't define the sbrk() function as the base function needed for malloc to allocate more memory.

So a sketch like

#include <Arduino.h>

void setup() {
    Serial.begin(115200);
}
static int i=0;
void loop() {
    Serial.println("Hello " + String(i++));
}

fails with

Linking .pio\build\ch32v003f4p6_evt_r0\firmware.elf
c:/users/max/.platformio/packages/toolchain-riscv/bin/../lib/gcc/riscv-none-embed/8.2.0/../../../../riscv-none-embed/bin/ld.exe: .pio\build\ch32v003f4p6_evt_r0\FrameworkArduino\api\String.cpp.o: in function `arduino::String::~String()':
String.cpp:(.text._ZN7arduino6StringD2Ev+0x4): undefined reference to `free'
c:/users/max/.platformio/packages/toolchain-riscv/bin/../lib/gcc/riscv-none-embed/8.2.0/../../../../riscv-none-embed/bin/ld.exe: .pio\build\ch32v003f4p6_evt_r0\FrameworkArduino\api\String.cpp.o: in function `arduino::String::invalidate()':
String.cpp:(.text._ZN7arduino6String10invalidateEv+0xc): undefined reference to `free'
c:/users/max/.platformio/packages/toolchain-riscv/bin/../lib/gcc/riscv-none-embed/8.2.0/../../../../riscv-none-embed/bin/ld.exe: .pio\build\ch32v003f4p6_evt_r0\FrameworkArduino\api\String.cpp.o: in function `arduino::String::changeBuffer(unsigned int)':
String.cpp:(.text._ZN7arduino6String12changeBufferEj+0x10): undefined reference to `realloc'
c:/users/max/.platformio/packages/toolchain-riscv/bin/../lib/gcc/riscv-none-embed/8.2.0/../../../../riscv-none-embed/bin/ld.exe: .pio\build\ch32v003f4p6_evt_r0\FrameworkArduino\api\String.cpp.o: in function `arduino::String::String(int, unsigned char)':
String.cpp:(.text._ZN7arduino6StringC2Eih+0x18): undefined reference to `itoa'

So it also uses -nostdlib which causes itoa to not be found and stuff.

If I do make the required fixes per Community-PIO-CH32V@d098d4d, I get a successfull compile

Linking .pio\build\ch32v003f4p6_evt_r0\firmware.elf
Checking size .pio\build\ch32v003f4p6_evt_r0\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [===       ]  25.8% (used 528 bytes from 2048 bytes)
Flash: [==        ]  19.9% (used 3260 bytes from 16384 bytes)

and it works during runtime.

Question is, do we want this? Should this be allowed usage on a chip with this little memory?

With the "main branch" / no malloc, a blinky sketch of

#include <Arduino.h>
#define LED C1
void setup() { pinMode(LED, OUTPUT); }
void loop() {
    digitalWrite(LED, HIGH);
    delay(1000);
    digitalWrite(LED, LOW);
    delay(1000);
}

uses

RAM:   [==        ]  18.4% (used 376 bytes from 2048 bytes)
Flash: [=         ]   8.7% (used 1420 bytes from 16384 bytes)

and with the malloc branch it uses

RAM:   [==        ]  24.6% (used 504 bytes from 2048 bytes)
Flash: [=         ]  11.2% (used 1832 bytes from 16384 bytes)

So.. even though this sketch shouldn't use malloc, the compiler still adds some baggage, probably because of the nosys and nano specs linking.. :(

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions