Open-CMSIS-Pack / devtools

Open-CMSIS-Pack development tools - C++
Apache License 2.0
76 stars 59 forks source link

AC6 Linker Script Improvement: region RAM1 ... RAM3 is not used when RAM0 is full #1778

Open ReinhardKeil opened 2 months ago

ReinhardKeil commented 2 months ago

The Problem To Be Solved

The AC6 linker script uses *(+RW +ZI) instead of .ANY. This creates a problem: when region RAM0 is full it is expected that RAM1...3 regions are used. However this does not work due to the * usage in RAM0 region.

The reason why * instead of .ANY is used, is the AlignExpr(ImageLength(RW_NOINIT) in https://github.com/Open-CMSIS-Pack/devtools/blob/main/tools/projmgr/templates/ac6_linker_script.sct.src#L51

Workaround is explicit placement of sections.

chentang16 commented 2 months ago

One potential solution/workaround would be as follows: RW_RAM0 AlignExpr(+0, 8) { .ANY1 (+RW +ZI) } ... RW_RAM1 __RAM1_BASE __RAM1_SIZE { .ANY2 (+RW +ZI) } ... RW_RAM2 __RAM2_BASE __RAM2_SIZE { .ANY2 (+RW +ZI) } ScatterAssert(ImageLength(RW_RAM0) < (__RAM0_SIZE - __HEAP_SIZE - __STACK_SIZE - __STACKSEAL_SIZE - AlignExpr(ImageLength(RW_NOINIT), 8)) In such a case, RW_RAM1, RW_RAM2 etc. will be filled with (+RW +ZI) first and then followed by RW_RAM0: https://developer.arm.com/documentation/101754/0622/armlink-Reference/Scatter-loading-Features/Manual-placement-of-unassigned-sections/Prioritizing-the-placement-of-unassigned-sections?lang=en

The overflows of RW_RAM0 can be checked using the function ScatterAssert(). Such an assert is evaluated at the end of the link so that all sizes are known: https://developer.arm.com/documentation/101754/0622/armlink-Reference/Scatter-File-Syntax/Expression-evaluation-in-scatter-files/ScatterAssert-function-and-load-address-related-functions?lang=en

I have made a simple test with a Cortex-M7 example, which works as expected