maxgerhardt / pio-gd32f130c6

Test project for the GigaDevice's GD32F130C6 using PlatformIO
7 stars 2 forks source link

Issues with the build without copy/paste the framework-spl #3

Closed EFeru closed 3 years ago

EFeru commented 3 years ago

Hi Max,

I just tried the new way you wrote in platfomio.ini for compiling GD projects. I compiled on my project: https://github.com/EmanuelFeru/hoverboard-sideboard-hack-GD

And I encountered two issues:

  1. The VARIANT_DEBUG does not build, see error:

    c:/users/37ef/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc_nano.a(lib_a-sbrkr.o): In function `_sbrk_r':
    sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
    c:/users/37ef/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc_nano.a(lib_a-closer.o): In function `_close_r':
    closer.c:(.text._close_r+0xc): undefined reference to `_close'
    c:/users/37ef/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc_nano.a(lib_a-lseekr.o): In function `_lseek_r':
    lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
    c:/users/37ef/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc_nano.a(lib_a-readr.o): In function `_read_r':
    readr.c:(.text._read_r+0x10): undefined reference to `_read'
    c:/users/37ef/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc_nano.a(lib_a-fstatr.o): In function `_fstat_r':
    fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
    c:/users/37ef/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc_nano.a(lib_a-isattyr.o): In function `_isatty_r':
    isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
    collect2.exe: error: ld returned 1 exit status
    *** [.pio\build\VARIANT_DEBUG\firmware.elf] Error 1
    =================================================================================== [FAILED] Took 3.74 seconds ===================================================================================
  2. The VARIANT_HOVERBOARD is larger in the new compilation:

Before:

RAM:   [=         ]  10.6% (used 436 bytes from 4096 bytes)
Flash: [=======   ]  68.1% (used 22300 bytes from 32768 bytes)

After:

RAM:   [=         ]  11.3% (used 464 bytes from 4096 bytes)
Flash: [=======   ]  68.3% (used 22388 bytes from 32768 bytes)

Note1: For the "after" I did a pio update in my terminal and now I cannot run the case before anymore. Luckily I have 2 laptops, and on one laptop I could run the before case. But I don't feel to run a pio update on my 2nd laptop, because I won't be able to build code for the VARIANT_DEBUG at all.

Note2: The only thing I changed was platformio.ini file. Code is untouched, exactly as in my repo.

Note3: You can find the attached files for more details: platformio.ini and complete Terminal log. GD32_platformio.zip

Do you have an idea about the issues above and how solve it? The increase in size maybe I can deal with it but with the fact that it does not build I need to fix it.

maxgerhardt commented 3 years ago

I suspect it has something to do with updates to the ststm32 platform. I'll just quickly iterate through a few platform = ststm32@.. versions from https://github.com/platformio/platform-ststm32/releases.

Although using the newest platform version (and thus compiler and everything) would also be a nice thing maybe.

The first error looks.. weird. These functions that the compiler cannot find should be in some low-level C library or glue code. I'll check.

EFeru commented 3 years ago

Yes, preferably I would like to use the updated platform. Because new people will use the new platform and that means they won't be able to build at the moment. So, it would be very nice if I can fix it somehow.

Edit I have just seen that:

maxgerhardt commented 3 years ago

Yes setting

[env:VARIANT_DEBUG]
platform        = ststm32@5.7.0

(and same in other env) makes the variant compile again and brings the other variant back to size

RAM:   [=         ]   9.8% (used 400 bytes from 4096 bytes)
Flash: [==========]  95.8% (used 31384 bytes from 32768 bytes)
Building .pio/build/VARIANT_DEBUG/firmware.bin
..
Building .pio/build/VARIANT_HOVERBOARD/firmware.bin
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]  10.6% (used 436 bytes from 4096 bytes)
Flash: [=======   ]  68.1% (used 22300 bytes from 32768 bytes)

So if you want the same compilation result you can pin the ststm32 version.

For the current version, I've investigated https://stackoverflow.com/questions/13235748/linker-error-on-a-c-project-using-eclipse and found the -Wl,-specs=nosys.specs with which things compile, but compile wrongly (either 0 firmware size or very small). I'll further investigate.

Since the other platform might use a slightly different setting or compiler, I don't think the flash size can be reduced by those added 88 bytes again, but that's small anyways.

maxgerhardt commented 3 years ago

Meh. I think the VARIANT_DEBUG is a lost cause in the new platform version. Modifying the add_nanolib.py to do

env.Append(LINKFLAGS=["--specs=nosys.specs", "--specs=nano.specs"])

makes the undefined references go away but also overflows flash by 408 bytes. So the firmware size increased from 31384 to 33248 with the new platform.

Linking .pio/build/VARIANT_DEBUG/firmware.elf
/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: .pio/build/VARIANT_DEBUG/firmware.elf section `.data' will not fit in region `FLASH'
/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 480 bytes
collect2: error: ld returned 1 exit status

One could now investigate what exactly the compiler flag differences are, and the compiler itself, the memory .map files and each symbol and size included in the ELF but.. I think it's just safer to use the old platform version? :D

And it may even compile with platforms beyond 5.7.0 to get to some more recent releases.

EFeru commented 3 years ago

I confirm that I managed to restore the Before results using.

platform        = ststm32@5.7.0

Increased size I can deal with it, maybe I try few optimizations. However, using the newer platform would be nice.

maxgerhardt commented 3 years ago

For the "release" version that would be no problem (+80 bytes), but the debug variant overflows when the undefined references are resolved and thus compiled in.. One may be able to analyze the binary and see why exactly _sbrk is needed now (which functions calls it?) and if it was in the previous version at all, and in which size. Can be done with tools but tedious.

The interesting thing is: Even this project here does not compile anymore if you activate printf() in main.c, with the same error types.

Compiling .pio/build/GD32F130C6T6/src/main.o
Linking .pio/build/GD32F130C6T6/firmware.elf
/home/max/.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'
/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x12): undefined reference to `_lseek'
/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x12): undefined reference to `_read'
/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x10): undefined reference to `_fstat'
/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
collect2: error: ld returned 1 exit status

I'll double check whether nosys.specs is the right way to fix this.

Edit: Removing the nanolibs also doesn't make the error go away.

Edit 2: Ah maybe it needs some of this glue code... https://github.com/joeferner/stm32-utils/blob/master/syscalls.c

Edit 3: Yes adding the glue code, without the _write definition because it would be double otherwise, also gets rid of the undefined references problem, but the firmware still doesn't fit. In fact, it overflows by ~60 bytes more than previously. So "nosys" actually seems to be pretty optimal already.

/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: .pio/build/VARIANT_DEBUG/firmware.elf section `.data' will not fit in region `FLASH'
/home/max/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 472 bytes
collect2: error: ld returned 1 exit status
*** [.pio/build/VARIANT_DEBUG/firmware.elf] Error 1
EFeru commented 3 years ago

I tried what you said, indeed the errors disappeared but and I get an overflow. So with the new platform the code increased with 1864 ... seems significant. So I have to choose:

I tend to go more for code optimization and use new platform, if you find more please let me know.

The interesting thing is: Even this project here does not compile anymore if you activate printf() in main.c, with the same error types.

interesting. So it is the prinftf

maxgerhardt commented 3 years ago

I've fixed this project in case the printf() is used by linking with nosys.specs per commit 9d10d9d337214d327690d6ede6fb2ac9a60f7fbe. That makes it compile with the newest platform, under a size increase which might have other factors than needing nosys -- I think that's unavoidable.

With printf() the firmware is now

RAM:   [          ]   3.7% (used 152 bytes from 4096 bytes)
Flash: [=         ]  13.9% (used 4568 bytes from 32768 bytes)

and with the old platform it was smaller.

RAM:   [          ]   3.0% (used 124 bytes from 4096 bytes)
Flash: [=         ]  13.7% (used 4480 bytes from 32768 bytes)
EFeru commented 3 years ago

So to conclude, do I need this new file syscalls.txt? Or I can skip it, because also without it was working but with overflow.

maxgerhardt commented 3 years ago

Since it's a .txt file it won't be compiled in, it's not needed. I just included this in the repo for reference as an alternative and documentation.

EFeru commented 3 years ago

I see. I found something very interesting. If I now remove the -Wl, the code is much smaller and it builds, Debug variant:

RAM:   [=         ]  10.4% (used 428 bytes from 4096 bytes)
Flash: [==========]  96.0% (used 31472 bytes from 32768 bytes)

I changed to this (without -Wl):

build_flags =
    -IInc
    -ISrc 
    -DUSE_STDPERIPH_DRIVER
    -DGD32F130_150
    -T./GD32F130C6T_FLASH.ld
    -lc
    -lm
    -g -ggdb
    -D VARIANT_DEBUG

Edit: What is -Wl actually doing? I inherited it from an older project.

EFeru commented 3 years ago

I will see where I can optimize the code to reduce the size further, because it is very close to the limit. Thank you for the very quick help!