fix(linker): correct cross-toolchain memory map inconsistencies - #11
fix(linker): correct cross-toolchain memory map inconsistencies#1194xhn wants to merge 2 commits into
Conversation
…CLEO-U031R8 Cross-checked the GCC (STM32CubeIDE), IAR (EWARM) and Keil (MDK-ARM) memory maps of every NUCLEO-U031R8 project against each other and against the STM32U031R8Tx datasheet (64 KB Flash / 12 KB SRAM). Two real drifts were found and fixed: 1. Examples/FLASH/FLASH_FastProgram The README explicitly states "All the executable code is mapped in SRAM1 area", and both the IAR linker script (EWARM/stm32u031xx_sram.icf) and the Keil project (MDK-ARM/FLASH_FastProgram.uvprojx, OCR_RVCT4) place the code region at 0x20000000/8 KB in SRAM instead of at 0x08000000 in Flash. The STM32CubeIDE linker script (STM32U031R8TX_FLASH.ld) was never updated to match: it still places .isr_vector/.text/.rodata in the physical Flash region. Since STM32U031 Flash has no read-while-write capability, a GCC build of this example would execute from Flash while the demo itself erases/programs that same Flash bank, which is invalid on this device. Fixed by mirroring the SRAM execution layout already used by GCC in the equivalent FLASH_FastProgram example of the STM32G4 family (STM32CubeG4 NUCLEO-G431KB/G431RB, *_SRAM.ld): FLASH region moved to 0x20000000/8 KB (code), RAM region moved to 0x20002000/4 KB (data/stack/heap), for a total of 12 KB matching the device's physical SRAM. The Keil project's IRAM1 data region (OCR_RVCT9) was also wrong: it declared 0x4000 (16 KB) at 0x20002000, which together with the 8 KB code region exceeds the device's total 12 KB physical SRAM. Corrected to 0x1000 (4 KB) to match the IAR icf and the device's real SRAM size. 2. Examples/PWR/PWR_ModesSelection The Keil project (MDK-ARM/PWR_ModesSelection.uvprojx) declared the device memory map of a different, larger STM32U0 part: IROM 0x08000000/256 KB and IRAM 0x20000000/32 KB, along with a FlashDriverDll pointing at the STM32U0xx_256k.FLM algorithm. STM32U031R8Tx only has 64 KB Flash / 8 KB usable SRAM, as confirmed by every other Keil project for this same board (Templates, all other ~25 Examples/Examples_LL projects) and by the GCC/IAR linker scripts of this same example, which correctly use 64 KB/8 KB. Corrected the <Cpu> tag, FlashDriverDll (now STM32U0xx_64k.FLM / -FL010000), and the OnChipMemories IRAM/IROM/OCR_RVCT4/OCR_RVCT9 entries to the correct 0x08000000/64 KB and 0x20000000/8 KB values, matching every sibling example project. No local ARM toolchain was available to rebuild the projects; the fix was verified purely by address/size arithmetic and by cross-referencing sibling example projects and precedent from the equivalent example in the STM32CubeG4 repository. Signed-off-by: 94xhn <87560781+94xhn@users.noreply.github.com>
|
Hello @94xhn, Thank you for your report, after deep investigation and our documentations reviewing, I believe that the original RAM and Flash memories and their size is correct. According to the documentations:
You can find the evidence below extracted from the following documents: (Reference manual & Datasheet)
Also, there is a simple way to know the flash memory size through ordering information section in the Datasheet for each device reference: Therefore, would you mind allowing to close this issue. Best Regards, |
|
Hello @94xhn, I have returned to the second point in Examples/PWR/PWR_ModesSelection, and I noticed that your point seems to make sense only partially, because according to the SRAM size, there are two SRAMs, SRAM1 and SRAM2, and we should maintain both of them. Best Regards, |
The STM32U031R8 exposes an 8 KiB SRAM1 bank and a 4 KiB SRAM2 bank. Align the PWR example device metadata and on-chip memory regions with the repository's canonical U031R8 template while retaining the corrected 64 KiB Flash definition. Constraint: Match the same-device MDK template and the PWR example's SRAM2 retention scenario Rejected: Keep only SRAM1 | the project explicitly exercises SRAM2 retention and the device template exposes both banks Confidence: high Scope-risk: narrow Directive: Keep the two physical SRAM banks distinct in MDK memory metadata Tested: XML parse, exact field comparison with Templates/MDK-ARM, SRAM interval arithmetic, git diff --check Not-tested: MDK-ARM build is unavailable locally
|
Thanks for catching that, @MKISTM. You're right: the STM32U031R8 has 8 KiB SRAM1 at 0x20000000 and 4 KiB SRAM2 at 0x20002000. I updated the MDK device metadata and second RAM region to match the repository's U031R8 template while keeping the corrected 64 KiB Flash definition; the XML and address-range checks pass. |
|
ST Internal Reference: 59cee5dd83da4f102ea7dbb0ecda1e86 |



Summary
I cross-checked the GCC (STM32CubeIDE
.ld), IAR (EWARM.icf) andKeil (MDK-ARM
.uvprojx) memory maps of every project underProjects/NUCLEO-U031R8against each other, using theTemplatesproject of the same board as the reference ("gold") memory map, and
against sibling projects/repositories where a project-local reference
was not conclusive. Two real, isolated cross-toolchain drifts were
found and fixed. All other apparent mismatches surfaced during the
audit were investigated and confirmed to be false positives (see
"Findings ruled out" below).
1.
Examples/FLASH/FLASH_FastProgram— GCC linker script never redirects execution to SRAMreadme.html/README.mdexplicitly states: "All the executablecode is mapped in SRAM1 area".
EWARM/stm32u031xx_sram.icf(note the filename) whose
ROM_regionis0x20000000–0x20001FFF(SRAM, not Flash).
MDK-ARM/FLASH_FastProgram.uvprojx) has itsactive code region
OCR_RVCT4(enabled viaIr1Chk) pointing at0x20000000/0x2000, i.e. also SRAM.(
STM32CubeIDE/STM32U031R8TX_FLASH.ld) was the only outlier: itstill places
.isr_vector/.text/.rodatain the physical Flashregion (
0x08000000, 64 KB), unchanged from the generic template.STM32U031 Flash has no read-while-write/dual-bank capability, so a
GCC/STM32CubeIDE build of this example would fetch instructions from
the same Flash bank that the demo itself erases and fast-programs —
undefined behavior on this device (at best a bus fault/lock-up during
the demo, at worst silent corruption). IAR and Keil avoid this by
running from SRAM as documented; GCC did not.
Fix: mirrored the SRAM-execution layout already used for the
identical
FLASH_FastProgramexample in the STM32G4 family, whereGCC ships a dedicated
*_SRAM.ld(
STM32CubeG4/Projects/NUCLEO-G431KB/Examples/FLASH/FLASH_FastProgram/STM32CubeIDE/STM32G431KBTX_SRAM.ld)using the same "FLASH region aliased into SRAM" trick:
8 KB (code) + 4 KB (data/stack/heap) = 12 KB, matching the device's
physical SRAM and exactly matching the IAR icf's
ROM_region(8 KB at
0x20000000) and the intendedRAM_regionsize.While investigating this, I also found the Keil project's
IRAM1data region (
OCR_RVCT9) declared0x4000(16 KB) at0x20002000,which combined with the 8 KB code region exceeds the device's total
12 KB physical SRAM by 12 KB. Corrected to
0x1000(4 KB) to matchthe IAR icf's
RAM_regionand the physical SRAM size.2.
Examples/PWR/PWR_ModesSelection— Keil project uses a different device's memory mapThe Keil project (
MDK-ARM/PWR_ModesSelection.uvprojx) declared:i.e. 256 KB Flash / 32 KB+8 KB RAM, and a
FlashDriverDllpointing atthe
STM32U0xx_256k.FLMalgorithm with-FL040000(256 KB). Thisexactly matches a different STM32U0 part (e.g. STM32U083, which
does have 256 KB Flash / 32 KB RAM per
TemplatesofSTM32U083C-DK), not the STM32U031R8Tx (<Device>tag) actuallytargeted by this project, which has 64 KB Flash / 8 KB usable SRAM.
Every other Keil project for this exact board —
Templates,Templates_LL, and all ~25 otherExamples/Examples_LLprojects —uses:
and an empty (or
STM32U0xx_64k.FLM-based)FlashDriverDll. TheGCC and IAR memory maps of this same
PWR_ModesSelectionexample arealready correct (64 KB/8 KB), so this was Keil-only drift, most
likely from copying a Keil project template/OCR block from a
different, larger STM32U0 device without updating the memory size
fields.
Fix: corrected
<Cpu>,FlashDriverDll, and theOnChipMemoriesIRAM/IROM/OCR_RVCT4/OCR_RVCT9entries to0x08000000/64 KBand
0x20000000/8 KB, matching every sibling example for this board.Findings ruled out (false positives / not fixed)
Applications/ROT/OEMiSB_AppliandOEMiSB_Boot(NUCLEO-U031R8):Keil OCR mismatches are inert — both projects set
<ScatterFile>stm32u0xx_app.sct</ScatterFile>, so the real memorymap comes from the
.sctscatter file (which is correct), not theOCR_RVCT fields. The IAR "1-byte ROM" discrepancy my scanning
script initially reported is a parsing artifact: the
.icfusesexpression-based addresses (e.g.
0x08000000 + FLASH_BOOT_AREA_SIZE - SHA_AREA_SIZE) that a naiveregex can't evaluate; the real region sizes match the GCC
.ldexactly once the arithmetic is evaluated by hand.
Applications/ROT/OEMiROT_AppliandTemplates_ROT(NUCLEO-U083RC): same expression-parsing artifact
(
CODE_OFFSET/CODE_SIZEcomputed from the pairedOEMiROT_Bootproject); the secure/non-secure partitioning isintentional and internally consistent.
Demonstration/Demo(STM32U083C-DK): the scan matched an unused,orphaned
EWARM/stm32u083xx_sram.icffile. The actual active IARbuild configuration (
STM32U083C_DK_Demo.ewp→IlinkIcfFile=stm32u083xx_flash.icf) matches GCC/Keil/goldexactly; the sram icf is not referenced by any build configuration.
Applications/OpenBootloader(STM32U083C-DK): IAR restricts thebootloader to 32 KB Flash / 13 KB RAM while GCC/Keil use the full
256 KB/32 KB. This is a genuine, active discrepancy, but I could
not establish with confidence which side is correct: precedent
from sibling repositories is contradictory (STM32CubeC0's
OpenBootloaderrestricts all three toolchains identically to asmall partition, while STM32CubeG4's
NUCLEO-G491REOpenBootloaderleaves GCC and IAR both unrestricted), and thisapplication links USBX (DFU over USB), which could plausibly
exceed 32 KB, making a blind "shrink GCC/Keil to match IAR" fix
potentially a build-breaking regression. I'm leaving this out of
the PR and flagging it here in case a maintainer with the actual
build size numbers wants to resolve it.
Test plan
No ARM toolchain (GCC/IAR/Keil) is available in this environment, so
I could not compile/link either project to confirm the map file
output. Verification was done by:
against the device's total Flash/RAM as documented in this
repository's own
Templateslinker scripts and theSTM32CubeIDE.ldheader comments (64Kbytes FLASH/12Kbytes RAMfor STM32U031R8Tx).Examples/Examples_LLprojects for NUCLEO-U031R8 to confirm the"correct" memory values used in the fix.
FLASH_FastProgramexample inSTM32CubeG4 (
NUCLEO-G431KB/NUCLEO-G431RB), which alreadyships a working GCC
*_SRAM.ldfor the same kind of demo, toconfirm the linker-script structure used in the fix.
.uvprojxfiles remain well-formed XML(
xml.etree.ElementTree.parse).Disclosure
I used Claude (Anthropic) as an AI coding assistant to help scan,
cross-reference, and draft this fix. I (the human submitter)
personally reviewed every file mentioned above, verified the address
arithmetic by hand, and take responsibility for the correctness of
this PR.