Error on stm32, arduino and sprintf

When I compile my project I got this error.

/home/ikeji/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to '_sbrk'
collect2: error: ld returned 1 exit status

Here is my platformio.ini:

[env:bluepill_f103c8]
platform = ststm32
board = bluepill_f103c8
framework = arduino

and src:

void setup(){
  char buf[256];
  sprintf(buf, "%d",10);
}
void loop(){
}

Is there any way to get _sbrk function?

I can confirm that this is an issue.

Now the weird thing is that the _sbrk is present in the syscalls.c file for the board varaint (.platformio\packages\framework-arduinoststm32\STM32F1\variants\generic_stm32f103c\wirish\syscalls.c), and it also gets compiled and archived into the FrameworkArduinoVariant.a which gets linked in during the final step where the firmware.elf is produced. I have confirmed by using IDA and arm-none-eabi-nm that the symbol _sbrk indeed gets exported by syscalls.c.o, so I have no idea why the linker doesn’t find it…

Have you also tried this inside Arduino-IDE? If it also doesn’t work there I suggest you open a issue on their github at GitHub - stm32duino/Arduino_Core_STM32: STM32 core support for Arduino.

Thanks for confirm the issue.

I think the correct repo for this framework is here:

I tried using this framework in Arduino-IDE and it’s works.

Someone already reported this issue to this framework,
but the owner suggests to ask in platformio side because it’s happen in platformio only.

Thanks,

Oh you are right about the github link, my bad.

Yes that’s really interesting. The discussion at http://stm32duino.com/viewtopic.php?f=41&t=2434&start=80#p33786 outlines the way that problem was apparently solved. In the first solution they added -u flags to the linker (docs) to force inclusion, but that didn’t work for me. I tried doing this in my platformio.ini

build_flags = -Wl,--unresolved-symbols=report-all -Wl,--start-group -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid -Wl,--end-group 

but the build process failed early on when libFrameworkArduino.a was created without the libFrameworkArduinoVariant.a being present first?

arm-none-eabi-ar rc .pioenvs\bluepill_f103c8\libFrameworkArduino.a .pioenvs\bluepill_f103c8\FrameworkArduino\HardwareSerial.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\HardwareTimer.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\IPAddress.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\Print.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\Stream.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\WString.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\avr\dtostrf.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\cxxabi-compat.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\ext_interrupts.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\hooks.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\itoa.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\adc.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\adc_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\bkp_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\dac.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\dma.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\dma_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\exc.S.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\exti.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\exti_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\flash.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\fsmc_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\gpio.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\gpio_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\i2c.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\i2c_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\iwdg.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\nvic.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\pwr.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\rcc.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\rcc_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\spi.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\spi_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\stm32f1\performance\isrs.S.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\stm32f1\performance\vector_table.S.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\systick.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\timer.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\timer_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usart.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usart_f1.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usart_private.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usb\stm32f1\usb.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usb\stm32f1\usb_cdcacm.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usb\stm32f1\usb_reg_map.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usb\usb_lib\usb_core.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usb\usb_lib\usb_init.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usb\usb_lib\usb_mem.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\usb\usb_lib\usb_regs.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\libmaple\util.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\main.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\new.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\pwm.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\sdio.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\stm32f1\util_hooks.c.o .pioenvs\bluepill_f103c8\FrameworkArduino\stm32f1\wiring_pulse_f1.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\stm32f1\wirish_debug.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\stm32f1\wirish_digital_f1.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\tone.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\usb_serial.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\wirish_analog.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\wirish_digital.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\wirish_math.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\wirish_shift.cpp.o .pioenvs\bluepill_f103c8\FrameworkArduino\wirish_time.cpp.o
arm-none-eabi-ranlib .pioenvs\bluepill_f103c8\libFrameworkArduino.a
*** [.pioenvs\bluepill_f103c8\firmware.elf] Implicit dependency `C:\Users\Maxi\.platformio\platforms\ststm32\builder\_sbrk' not found, needed by target `.pioenvs\bluepill_f103c8\firmware.elf'.
 [ERROR] Took 6.88 seconds 

I then tried the other way (their second solution) to include the compiled syscall object file to the linker using the absolute path of that file which was compiled in a previous run:

build_flags =  -Wl,--start-group "C:\Users\Maxi\Documents\bluepill_mbed\.pioenvs\bluepill_f103c8\FrameworkArduinoVariant\wirish\syscalls.c.o"  -Wl,--end-group

With that, it builds.

arm-none-eabi-g++ -o .pioenvs\bluepill_f103c8\firmware.elf -Os -Wl,--gc-sections,--relax -mthumb -mcpu=cortex-m3 -Wl,--start-group -Wl,--end-group -Wl,-T"jtag_c8.ld" .pioenvs\bluepill_f103c8\src\main.cpp.o -LC:\Users\Maxi\.platformio\platforms\ststm32\ldscripts -LC:\Users\Maxi\.platformio\packages\framework-arduinoststm32\STM32F1\variants\generic_stm32f103c\ld -L.pioenvs\bluepill_f103c8 -Wl,--start-group .pioenvs\bluepill_f103c8\libFrameworkArduinoVariant.a .pioenvs\bluepill_f103c8\libFrameworkArduino.a -lgcc -lm .pioenvs\bluepill_f103c8\FrameworkArduinoVariant\wirish\syscalls.c.o -Wl,--end-group
arm-none-eabi-size -B -d .pioenvs\bluepill_f103c8\firmware.elf
arm-none-eabi-objcopy -O binary .pioenvs\bluepill_f103c8\firmware.elf .pioenvs\bluepill_f103c8\firmware.bin
text	   data	    bss	    dec	    hex	filename
14596	   3200	   1288	  19084	   4a8c	.pioenvs\bluepill_f103c8\firmware.elf
 [SUCCESS] Took 6.72 seconds 

At least there’s an ugly solution. Let’s see what @ivankravets thinks about that, as it seems that PIOs build system needs to add some special linker flags for it.

Really makes we wonder how noone every noticed that error before. Without _sbrk there’s also no malloc or any new operator working. Funny.

I couldn’t confirm but this was work few weeks back.

Today, I met separate problem (tone function doesn’t work) and re-installed platformio.
After the re-install, this no longer compile.

Same issue as the OP with a generic_stm32f103c. Happened after updating to latest Stm32 4.0.1. Hope this can be solved soon.

Thank you

Temporary workaround: add the following snippet to one of your source files and rebuild:

extern "C" void *_sbrk(int incr);
void dummy_sbrk_caller() __attribute__((__used__));
void dummy_sbrk_caller()
{
  _sbrk(0);
}

Explanation is here. The libraries linking order is wrong. libFrameworkArduinoVariant provides _sbrk but goes before libc that uses it, that’s why linker throws _sbrk away. It wasn’t used in object files before libFrameworkArduinoVariant inclusion.

1 Like

Fixed in Release 4.0.2 · platformio/platform-ststm32 · GitHub. Please navigate to PIO Home > Platforms > Updates.

Thanks for fix this!