modm-io / modm-devices

Curated device data for all AVR and ARM Cortex-M devices
https://blog.salkinium.com/modm-devices
Mozilla Public License 2.0
50 stars 28 forks source link

STM32L431 RAM configuration is wrong #33

Closed mikewolfram closed 4 years ago

mikewolfram commented 4 years ago

This MCU has a total RAM of 64kB, divided into 48kB SRAM1 and 16kB SRAM2. modm configures both of a size of 32kB. Not sure where the error comes from, looking at similar MCU their configuration is fine. Neither I have an idea how to fix that. So I'd ask for help. :-)

Not sure if it would be part of modm-devices as well, maybe the linker script could be updated to include SRAM2 section as well? Switching the MCU to a power savings mode retains SRAM2 only.

salkinium commented 4 years ago

You're running into the limitations of the CubeMX data, which only contains the combined SRAM size, but not how it is partitioned. This info is added manually from here, and is thus prone to human error (those pesky humans). The L431 needs to go into the next entry (SRAM1 = SRAM - SRAM2 = 48kB)?

The SRAM2 is intentionally removed by modm here. This limitation was added waaaaay back in xpcc and ported to modm. Unfortunately I forgot why we removed SRAM2 on STM32L4 (cc @strongly-typed).

Maybe just try it out and see what breaks?

mikewolfram commented 4 years ago

Well, did the changes and the SRAM2 is now part of the heap. No issues so far, but curious to know possible problems.

Add SRAM2 to the heap is ok for a typical application. Guess I'll change my linker script to use it instead as a separate backup data section.

Will create the PR the following days...

salkinium commented 4 years ago

I have something vague about address remapping for this section in my head, but I cannot find anything wrong with the l431.

Regarding heap: on my ToDo list is to add a lbuild enumeration set option to allow the user to choose which memories to use as heap. That way you can manage memories the way you want. The changes should be fairly small to do, if you want to try.

mikewolfram commented 4 years ago

The data sheet says, SRAM1 is located at 0x2000 0000 and SRAM2 at 0x1000 0000. SRAM2 is also mapped to 0x2000 C000 offering contiguous address space with SRAM1. I'd expect no issues in normal operation, not sure about when using the parity checking feature of SRAM2.

lbuild option sounds good, I was about to ask for it. :-) Would it be to choose heap areas only or would it be possible to use that option also to allow creating a second independent data section?

salkinium commented 4 years ago

Would it be to choose heap areas only

Yes, only heap section selection for this option.

would it be possible to use that option also to allow creating a second independent data section?

Not entirely clear what you mean by that, but you can add entirely new sections and memories via these string collectors. This is used to add the F469 Disco external memory into the heap structure.

mikewolfram commented 4 years ago

So I would choose the option to not use SRAM2 as heap, but rather define the section in the collectors. Looks reasonable.

mikewolfram commented 4 years ago

I've been looking into the data sheets of the several L4/L4+ MCU and came up with the following configuration:

    'l4': {
        'start': {
            'flash': 0x08000000,
            'eeprom': 0x08080000,
            'sram3': 0x20030000,
            'sram2': 0x10000000,
            'sram': 0x20000000
        },
        'model': [
            {
                'name': ['51', '71', '75', '76', '85', '86'],
                'memories': {'flash': 0, 'sram1': 0, 'sram2': 32*1024}
            },{
                'name': ['31', '32', '33', '42', '43', '52', '62'],
                'memories': {'flash': 0, 'sram1': 0, 'sram2': 16*1024}
            },{
                'name': ['96', 'a6'],
                'memories': {'flash': 0, 'sram1': 0, 'sram2': 64*1024}
            },{
                'name': ['r5', 'r7', 'r9', 's5', 's7', 's9'],
                'memories': {'flash': 0, 'sram1': 0, 'sram2': 64*1024, 'sram3': 384*1024}
            },{
                'name': ['12', '22'],
                'memories': {'flash': 0, 'sram1': 0, 'sram2': 8*1024}
            }
        ]
    },

What still confuses me are the starting addresses of the memories. E.g. SRAM3 starts at 0x2003 0000, but the data sheet tells 0x2004 0000. SRAM2 always starts at 0x1000 0000, but is also mapped between SRAM1 and SRAM3 to provide a contiguous memory. In that case its start address varies depending on SRAM1 size. Not sure how to make that correct.

What is the EEPROM address used for? None of the L4/L4+has EEPROM included, only L1.

salkinium commented 4 years ago

The start address computation is done in this mastercode of uglyness, where you can see some dynamic start address computation depending on SRAM1 size. Better add some print() calls, cos I don't even understand it anymore 🤪. That whole function needs to be nuked from orbit, everything is super unpythonic and god-classey. Horrible…

The EEPROM is probably just copy-pasted from the L1 series or something, only those memories that are keys of the memory model are used.

mikewolfram commented 4 years ago

While testing my changes I came across a problem. Running 'make generate-stm32l4' aborts with error, complaining about unknown devices stm32l4p5 and stm32l4q5. Looks like ST already included them in the STM32CubeMX, but searching for it on their web pages shows no matches.

To get around I added some dummy entries for the two MCU types.

When I did the same few weeks ago no problems occurred.

salkinium commented 4 years ago

complaining about unknown devices stm32l4p5 and stm32l4q5.

That's weird, I specifically added those devices a couple of weeks ago. The CI does generate these devices though, maybe remove the git repos in dfg/ext and redo make init?

Looks like ST already included them in the STM32CubeMX, but searching for it on their web pages shows no matches.

Yes, ST seems to "leak" their unannounced devices a few weeks before in CubeMX and sometimes also their CMSIS-Headers, I presume to give partners an easier time to test engineering samples. I added this code to first check if a cmsis header for the device is found, before continuing with the parsing.

mikewolfram commented 4 years ago

HEAD was detached, sorry, stupid mistake. Works now.