2023-01-18 09:53 AM
On other processors sometimes there are keywords when defining variables to specify which memory area the variable should be stored in. Or there is a #pragma statement.
I have not seen either in the STM32 or the IDE.
I am guessing RAM2 might be a good place to put DMA transfers so the processor working in RAM does not interfere as much with the transfer. But I do not know how to access it in any case.
According to the memory map SRAM1 starts at address 0x2000 0000 and SRAM2 starts at 0x2000 C000, (it drives me crazy when different documents use different names for the same thing) which makes me think they overlap? Unless the memory map is dealing in 32-bit dwords rather than 8-bit bytes. But then I would expect to see a gap between SRAM1 and SRAM2.
I see SRAM2 can be write protected. But still nothing about how to access it.
And SRAM2 can be retained in standby mode.
In the STM32L443CC STM32L443RC and STM32443VC datasheet (DS11421 Rev 5
On page 83/220 it says CODE memory goes from 0x0000 0000 to 0x1FFF FFFF.
SRAM1 goes from 0x2000 0000 to 0x2BFF FFFF and SRAM2 is from 0x2C00 0000 to undefined from the picture but less than 0x4000 0000 where the peripherals start.
But then it shows SRAM2 also from 0x1000 0000 to 0x1000 4000. So it has two mappings? How do you know which one to use?
Still I have not seen how to access it using the IDE.
Solved! Go to Solution.
2023-01-18 01:20 PM
Looks like that is what it did using:
uint16_t kbuffer[1024] __attribute__((section(".sram2")));
After that it was just like uninitialized memory.
Thanks for the response.
2023-01-18 02:34 PM
Dangerous. You did not reduce RAM size. The stack is placed at the end of RAM, so it effectively uses RAM2. The linker is unable to detect this overlap and to warn about full memory or stack overlapping your data in RAM2 cause it believes that your MCU has 64 + 16 KiB of RAM, which is not true. If you want to use RAM2 explicitly, reduce the size of main RAM in the linker script to 48 KiB.
2023-01-19 07:18 AM
Yes, that is next. For now I was just trying to make something work.
Thanks for your response.
2023-01-19 07:26 AM
Thanks for this. What is the purpose of "*(.sram2.*)"
Everything else I understand.
Except:
If every section starts with ". = ALIGN(4);" why is it needed at the end?
2023-01-19 08:21 AM
Depends on how the compiler generates objects.
The first star is all files/objects, the term in brackets is the section name the assembler/compiler outputs related to the symbol name.
You're explicitly naming via the __attribute__, but the tools can generate others within that name-space.
Remember you can have "static" names in every file that would conflict within the global name-space, so the compiler substitutes/adds file unique naming, and things like C++ add name mangling so as to differentiate functions of the same name, but working with different parameter types.
From .MAP file, showing what the filter is supposed to be capturing / corralling
...
.text.ADC_DiscModeChannelCountConfig
0x00000000 0x10 out/stm32f4xx_adc.o
.text.ADC_DiscModeCmd
0x00000000 0x12 out/stm32f4xx_adc.o
.text.ADC_GetConversionValue
0x00000000 0x6 out/stm32f4xx_adc.o
.text.ADC_GetMultiModeConversionValue
0x00000000 0xc out/stm32f4xx_adc.o
.text.ADC_DMACmd
0x00000000 0x12 out/stm32f4xx_adc.o
.text.ADC_DMARequestAfterLastTransferCmd
0x00000000 0x12 out/stm32f4xx_adc.o
.text.ADC_MultiModeDMARequestAfterLastTransferCmd
0x00000000 0x18 out/stm32f4xx_adc.o
.text.ADC_InjectedChannelConfig
0x00000000 0x54 out/stm32f4xx_adc.o
.text.ADC_InjectedSequencerLengthConfig
0x00000000 0x10 out/stm32f4xx_adc.o
.text.ADC_SetInjectedOffset
0x00000000 0x16 out/stm32f4xx_adc.o
.text.ADC_ExternalTrigInjectedConvConfig
0x00000000 0xc out/stm32f4xx_adc.o
.text.ADC_ExternalTrigInjectedConvEdgeConfig
0x00000000 0xc out/stm32f4xx_adc.o
.text.ADC_SoftwareStartInjectedConv
0x00000000 0xa out/stm32f4xx_adc.o
...
.text.SystemCoreClockUpdate
0x00000000 0x60 out/system_stm32f4xx.o
.rodata.AHBPrescTable.7483
0x00000000 0x10 out/system_stm32f4xx.o
.data.SystemCoreClock
0x00000000 0x4 out/system_stm32f4xx.o
From the .MAP, interpreting the .LD rules
.data 0x20000000 0x8b4 load address 0x08006124
0x20000000 . = ALIGN (0x4)
0x20000000 _sdata = .
*(.data)
*(.data*)
.data.APBAHBPrescTable
0x20000000 0x10 out/stm32f4xx_rcc.o
.data.__fdlib_version
0x20000010 0x1 c:/tools/gcc49_2014q4/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-s_lib_ver.o)
0x20000010 __fdlib_version
*fill* 0x20000011 0x7
.data.impure_data
0x20000018 0x428 c:/tools/gcc49_2014q4/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-impure.o)
.data._impure_ptr
0x20000440 0x4 c:/tools/gcc49_2014q4/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-impure.o)
0x20000440 _impure_ptr
.data.lconv 0x20000444 0x38 c:/tools/gcc49_2014q4/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-locale.o)
.data.lc_ctype_charset
0x2000047c 0x20 c:/tools/gcc49_2014q4/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-locale.o)
.data.__mb_cur_max
0x2000049c 0x4 c:/tools/gcc49_2014q4/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-locale.o)
0x2000049c __mb_cur_max
...
2023-01-19 08:34 AM
A lot of this is tool chain specific, but comes under college level "Assemblers, Compilers, Linkers, Loaders" type classes about the mechanics of these things.
Why ALIGN? well so that you meet the rules/expectations of the ARM ABI, that you don't create output that breaks when you add/remove code, and allow the linker to generate serviceable code at every invocation. Why ALIGN at the end? because it's your data structures that are likely to be oddly or variably sized, and this precludes a knock-on effect for other sections constructed by the linker later.
The linker script is a set of packaging and arrangement rules. It's very complex, and most people just cut-n-paste what they think works. I don't claim to be a GNU/GCC expert, but I understand the premise of what the end goal is here, and I can fiddle with things until they fit.
A lot of the symbols ST adds to the linker script allow it to track the placement in memory vs placement in the file/image, allowing the startup.s code to zero BSS, and copy initial state from the FLASH image to the RAM. If you add more sections, you'll need to initialize them properly. Tools like KEIL, IAR, and Arduino have the linker generate tables that startup code can unpack in a more automatic fashion.
2023-01-19 01:29 PM
Thanks for the complete explanation.
It has been over 40 years since I took a compiler class. Those neurons have not fired in a while.