stm32-rs / stm32l0xx-hal

A hardware abstraction layer (HAL) for the STM32L0 series microcontrollers written in Rust
BSD Zero Clause License
96 stars 60 forks source link

stm32l051k8u6 has 64kb of flash but is configured with 16kb #170

Closed azerupi closed 3 years ago

azerupi commented 3 years ago

Hi!

Unless I'm missing something, I think that the memory descriptions loaded are not always correct? I'm using for example a stm32l051k8u6 and stm32l071k8u6. According to the Cargo.toml of this hal it should activate the following features:

mcu-STM32L051K8Ux = ["stm32l0x1", "ufqfpn32", "io-STM32L051", "eeprom-2048"]

# Or

mcu-STM32L071K8Ux = ["stm32l0x1", "ufqfpn32", "io-STM32L071", "eeprom-3072"]

So they both fall under the stm32l0x1 group and that loads memory_l0x1.x according to the build.rs file. This defines that there is 16kb of flash. However on both of those MCUs the flash should be 64kb according to the datasheet.

MEMORY
{     
    FLASH : ORIGIN = 0x08000000, LENGTH = 16K     
    RAM : ORIGIN = 0x20000000, LENGTH = 2K
}

Screenshot from 2021-06-10 10-35-23 Screenshot from 2021-06-10 10-35-06

This causes some linking issues because the firmware is "too big" to fit in 16K although it works fine when I select the stm32l0x3 feature.

  1. Can I override the memory configuration in my code without changing this hal crate as a temporary workaround?
  2. Can we have more granularity in the flash memory configurations?
dbrgn commented 3 years ago

Can I override the memory configuration in my code without changing this hal crate as a temporary workaround?

Yes, you should be able to provide your own memory.x with the disable-linker-script Cargo feature:

https://github.com/stm32-rs/stm32l0xx-hal/blob/1324d0991d700a4363eaa84f9b7f65258a31cb51/build.rs#L24-L48

You'll need to provide your own memory.x in that case, something like this: https://github.com/gfroerli/firmware/blob/master/firmware/build.rs

Regarding the memory configuration, we generate those from STM32CubeMx, I'll have to check where the mismatch comes from.

dbrgn commented 3 years ago

Ah, I checked our cube-parse scripts. The memory mapping is generated based on the name, so all MCUs matching the RegEx ^STM32L0.1 will be mapped to memory_l0x1.x.

This may be wrong in a few cases, as you have noticed. Right now, the recommended way is to disable the automatic linker script and provide your own memory mapping. The included linker scripts are just there to get you started more easily.

However, we do have the information about the flash size in those XML files! For example, here's the MCU definition in STM32L071K8Ux.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Mcu ClockTree="STM32L0" DBVersion="V3.0" Family="STM32L0" HasPowerPad="true" IOType="" Line="STM32L0x1" Pa
ckage="UFQFPN32" RefName="STM32L071K8Ux" xmlns="http://mcd.rou.st.com/modules.php?name=mcu">
    <Core>Arm Cortex-M0+</Core>
    <Frequency>32</Frequency>
    <E2prom>3072</E2prom>
    <Ram>20</Ram>
    <IONb>23</IONb>
    <Die>DIE447</Die>
    <Flash>64</Flash>
...

...so I guess it shouldn't be too hard to generate better linker scripts based on this information.

azerupi commented 3 years ago

Great, thanks for the quick reply!

Right now, the recommended way is to disable the automatic linker script and provide your own memory mapping. The included linker scripts are just there to get you started more easily.

This might not be obvious for users. If a better 'fix' takes some time maybe we should warn the user to double check somewhere in the readme?

so I guess it shouldn't be too hard to generate better linker scripts based on this information.

I'll have a look to see how easy/hard it would be to make the change.

dbrgn commented 3 years ago

If a better 'fix' takes some time maybe we should warn the user to double check somewhere in the readme?

Yes, that would be great! Would you be willing to contribute a README PR that would have helped you?

I'll have a look to see how easy/hard it would be to make the change.

Main question would be how to pass that information from the generator to the build script. My first intuition would be flash-64 and ram-20 features that are automatically generated for the MCU. The build script would then emit different size parameters for the generated memory.x depending on the features. This would require a somewhat awkward if-festival in the build script (to check all possible features), but it would be in line with how we deal with other MCU differences right now.