platformio / platform-ststm32

ST STM32: development platform for PlatformIO
https://registry.platformio.org/platforms/platformio/ststm32
Apache License 2.0
389 stars 305 forks source link

STM32F303CC: Linker script doesn't know about 8KByte CCM RAM #340

Open maxgerhardt opened 4 years ago

maxgerhardt commented 4 years ago

As one can read in the discussion at https://community.platformio.org/t/robotdyn-blackpill-stm32f303cc-pio-has-wrong-max-ram-size/11521, the STM32F303CC chip (for which we have the board https://github.com/platformio/platform-ststm32/blob/develop/boards/robotdyn_blackpill_f303cc.json) has wrong RAM size information (datasheet). Specifically, the board has 40KB SRAM (starting at 0x20000000) and 8KB of core-coupled-memory (CCM) starting at 0x10000000. The board definition just says 40KB and the used linker script (https://github.com/platformio/platform-ststm32/blob/master/ldscripts/stm32f30xx.ld) references some completely mysterios "memory bank 1", which is only readable and executable, and of 0 length. So no mention of CCM_RAM at 0x10000000.

The linker script should be fixed to allow the creation of a section in which both code and data can be placed, at the correct address. User code will then have to use __attribute__ ((section ("ccm_ram")))-like instructions to place stuff in this linker memory section.

For now, the CCM RAM cannot be used with PIO.

valeros commented 4 years ago

Thanks for the report. Extra memory sections is a known issue and there is no default solution for this case at the moment, besides as I can see from the discussion that Arduino framework is used which means we don't have control over the default linker scripts.

A possible workaround is to manually increase RAM size in platformio.ini file using board_upload.maximum_ram_size = 49152.

maxgerhardt commented 4 years ago

Hm very interesting, you're right. The acutal final linking step uses /home/max/.platformio/packages/framework-arduinoststm32/variants/PILL_F303XX/ldscript.ld

arm-none-eabi-g++ -o .pio/build/robotdyn_blackpill_f303cc/firmware.elf -T /home/max/.platformio/packages/framework-arduinoststm32/variants/PILL_F303XX/ldscript.ld -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Os -mthumb -mcpu=cortex-m4 --specs=nano.specs -Wl,--gc-sections,--relax -Wl,--check-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--defsym=LD_MAX_SIZE=262144 -Wl,--defsym=LD_MAX_DATA_SIZE=40960 -Wl,--defsym=LD_FLASH_OFFSET=0x0 [..] -L/home/max/.platformio/platforms/ststm32/ldscripts -L.pio/build/robotdyn_blackpill_f303cc -L/home/max/.platformio/packages/framework-arduinoststm32/variants/PILL_F303XX -L/home/max/.platformio/packages/framework-arduinoststm32/CMSIS/CMSIS/DSP/Lib/GCC -Wl,--start-group -larm_cortexM4l_math -lc -lm -lgcc -lstdc++ -Wl,--end-group

And there the sections are correct

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 40K
CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 8K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 256K
}

[..]

  /* CCM-RAM section 
  * 
  * IMPORTANT NOTE! 
  * If initialized variables will be placed in this section,
  * the startup code needs to be modified to copy the init-values.  
  */
  .ccmram :
  {
    . = ALIGN(4);
    _sccmram = .;       /* create a global symbol at ccmram start */
    *(.ccmram)
    *(.ccmram*)

    . = ALIGN(4);
    _eccmram = .;       /* create a global symbol at ccmram end */
  } >CCMRAM AT> FLASH

So it is usable (with the note given above) and only the https://github.com/platformio/platform-ststm32/blob/master/ldscripts/stm32f30xx.ld has a problem, but isn't used by Arduino. I guess it's used for STM32Cube?

valeros commented 4 years ago

If I'm not mistaken, stm32f30xx.ld is a legacy linker script and it not used by any of the frameworks anymore.

Alteregoxxx commented 4 years ago

Thanks for the report. Extra memory sections is a known issue and there is no default solution for this case at the moment, besides as I can see from the discussion that Arduino framework is used which means we don't have control over the default linker scripts.

A possible workaround is to manually increase RAM size in platformio.ini file using board_upload.maximum_ram_size = 49152.

Oh, this would be actually great! Does this workaround still need that I have to explicitly use "attribute GCC" to use to that part of "special SRAM" (CCRAM) or is not necessary because it will be automatically managed behind the scenes by PlatformIO ?

valeros commented 4 years ago

@Alteregoxxx I'm not sure I understood your question correctly, but PlatformIO relies on maximum_ram_size value when checks whether the firmware will fit in your device, that's it. That workaround only bypasses this limitation. If you want to use this extra RAM section you need to specify attribute keyword and if I'm not mistaken you also need to modify startup routine because initial values for variables in CCRAM need to be copied from Flash when your device boots up.

Alteregoxxx commented 4 years ago

@Alteregoxxx I'm not sure I understood your question correctly, but PlatformIO relies on maximum_ram_size value when checks whether the firmware will fit in your device, that's it. That workaround only bypasses this limitation. If you want to use this extra RAM section you need to specify attribute keyword and if I'm not mistaken you also need to modify startup routine because initial values for variables in CCRAM need to be copied from Flash when your device boots up.

In the meantime I did a little bit of experimentation and it seems that only using the attribute keyword is sufficient to allow successful build of a firmware bigger than 40KB; hence, at least apparently, it seems it's not necessary to use board_upload.maximum_ram_size = 49152 in platformio.ini See here: BiggerRamF303

Later I will try also if the firmware runs correctly on the board

Thank you!