Often MCUs have several memory areas, e.g. STM32H7 (#5369) has:
- AXI SRAM (0x24000000) - 512KB continuous memory, currently available to TinyGo as RAM (bss and heap).
- D2 SRAM (0x30000000) - 288KB total (128+128+32), same silicon as AXI SRAM, just a different power domain (stays up in D2 low-power states, AXI SRAM doesn't). TinyGo currently doesn't have access to it.
- D3 SRAM (0x38000000) - SRAM4, 64KB, D3 domain, survives even deeper sleep (Stop mode), typically used for BDMA buffers since BDMA can only reach D3. TinyGo currently doesn't have access to it.
AXI + D2 + D3 don't form a continuous memory region, so they can't be easily bundled together and made available to TinyGo, but this also means we're effectively wasting 352 Kb of RAM.
Another caveat is that not all memory is made equal.
STM32F7 and some H7 CPUs for example, have TCM memory which can be accessed at 0 wait states, unlike the general RAM which is slower. DMA can't generally be used on TCM though. Similarly on STM32H75x - D3 is the only memory that survives clock stop and the only memory that supports BDMA.
This means we need to support some kind of NUMA memory allocation where we can either allocate from a particular memoy region at run-time or use //go: pragmas to place a statically allocated buffer into a defined memory region. GC and heap allocator will also need to support discontinuous memory.
A relatively simple approach could be as follows:
- We define additional memory sections (target-specific) and create a
//go:linksection pragma to control where the variable goes.
- We support some sort of arena allocator for non-heap memory allocated at run-time as an
unsafe.Pointer. Pointers into this memory are never GC'd.
Often MCUs have several memory areas, e.g. STM32H7 (#5369) has:
AXI + D2 + D3 don't form a continuous memory region, so they can't be easily bundled together and made available to TinyGo, but this also means we're effectively wasting 352 Kb of RAM.
Another caveat is that not all memory is made equal.
STM32F7 and some H7 CPUs for example, have TCM memory which can be accessed at 0 wait states, unlike the general RAM which is slower. DMA can't generally be used on TCM though. Similarly on STM32H75x - D3 is the only memory that survives clock stop and the only memory that supports BDMA.
This means we need to support some kind of NUMA memory allocation where we can either allocate from a particular memoy region at run-time or use
//go:pragmas to place a statically allocated buffer into a defined memory region. GC and heap allocator will also need to support discontinuous memory.A relatively simple approach could be as follows:
//go:linksectionpragma to control where the variable goes.unsafe.Pointer. Pointers into this memory are never GC'd.