/      日本語

RAM Allocation

RAM allocation
Describes RAM allocation.

RAM Allocation

The SRAM area of TWWLIET GOLD is as follows.

BASETOP (End + 1)SIZE
SRAM110x0402_C0000x0403_000016KB
SRAM100x0402_80000x0402_C00016KB
SRAM90x0402_40000x0402_800016KB
SRAM80x0402_00000x0402_400016KB
SRAM70x0401_50000x0401_60004KB
SRAM60x0401_40000x0401_50004KB
SRAM50x0401_20000x0401_40008KB
SRAM40x0401_00000x0401_20008KB
SRAM30x0400_C0000x0401_000016KB
SRAM20x0400_80000x0400_C00016KB
SRAM10x0400_40000x0400_800016KB
SRAM00x0400_00000x0400_400016KB

TWENET defines the memory map as follows.

BASETOPSizePurposeRETBank Name
Application Use0x0400_0000Decided at compile time~64KBRequired for MMAC linkingSRAM0..3
Heap0x0401_5000
(Changeable)
0x0401_5C003KBHeap area (malloc, new)SRAM7
Unused0x0402_00000x0402_C00048KBUnused areaSRAM8, 9, 10
SRAM11
Unused0x0402_C0000x0402_F00012KBUnused areaSRAM11
Stack0x0402_F0000x0403_00004KBStack areaSRAM11

(BASE: Start Address, TOP: End Address + 1, RET: RAM Retention during sleep)

  • The application use area is a static memory range determined at compile time. The end address can be referenced with (uint32)&_end_fw_retention. When sleeping, the system is set not to retain unnecessary banks based on the end address.
  • The heap area is a region allocated by malloc() and the new operator. Generally, repeated allocation and deallocation of this area can lead to fragmentation issues, so you should be mindful of this when implementing your application. The default setting allocates memory to SRAM bank 7. However, the last 512 bytes of bank 7 are reserved by the microcontroller’s semiconductor specifications, and the subsequent 512 bytes are reserved by TWENET.
    • This area can be adjusted by writing HEAP_START=0x04014000; and HEAP_SIZE = 8192 - BANK7_RESERVE; in App_User_Defs.ld (placed directly in the build directory).
      • HEAP_START is the start address of the heap, and HEAP_SIZE is the allocated size. Here are some typical combinations:
        • 0x04014000, 8192-BANK7_RESERVE (7KB, BANK6-7)
        • 0x04012000, 16384-BANK7_RESERVE (15KB, BANK5-7)
        • 0x04010000, 24576-BANK7_RESERVE (23KB, BANK4-7)
        • 0x0, 0 (set the maximum area, i.e., from _end_fw_rentention to 0x04016000-BANK7_RESERVE, as the HEAP)
  • The unused areas are SRAM8, 9, and 10, each with 16KB.
  • The stack area is set to the last 4096 bytes of SRAM11 (0x0403_0000) by default.
    • You can change the size of this area by writing STACK_SIZE = 8192; in App_User_Defs.ld (placed directly in the build directory). You can also specify the end address, such as STACK_TOP = 0x04024000;.
    • Please check _vStackTop and __StackLimit in the map file created in the build directory.
    • This area is not retained during sleep.

I’ve translated the text and formatted it as plain text to avoid the issue you mentioned earlier.

Setting the Retention Area during Sleep

The TWENET library is pre-configured to properly retain the necessary SRAM banks for the application use and heap areas during sleep. However, depending on the design and implementation of your application, you may want to retain banks that are not normally held. To do this, you can set the corresponding bits for any additional banks you need in the global variable G_TWENET_POWER_DOWN_RETENTION_CONFIG_ADD() defined in the TWENETcmpt library.

For example, if you want to retain 32KB of banks 8 and 9, specify the following before calling ToCoNet_vSleep() in the TWENET C library or the_twelite.sleep() in the mwx library.

G_TWENET_POWER_DOWN_RETENTION_CONFIG_ADD() = PM_CFG_SRAM_BANK8_RET | PM_CFG_SRAM_BANK9_RET;

Note: Increasing the amount of retained SRAM will also increase the sleep current.

App_User_Defs.ld Configuration Examples

If not specified, the HEAP will be from 0x0401_5000 to 0x0401_5FE0, and the STACK will be from 0x0402_F000 to 0x0403_0000. Below are examples for the .../build/App_User_Defs.ld configuration.

  • To allocate the maximum possible HEAP, from _end_fw_retention to 0x0401_5FE0:
HEAP_START = 0;
HEAP_SIZE = 0;
  • To allocate HEAP in RAM6 and 7 (approx. 8KB):
HEAP_START = 0x04014000;
HEAP_SIZE = 8192 - BANK7_RESERVE;
  • To set the HEAP from _end_fw_retention to 0x0401_5000 and the STACK from 0x0401_5000 to 0x0401_5FE0. (This makes BANK8..11 from 0x0402_0000 to 0x0403_0000 an unused area):
HEAP_TOP = 0x04015000;
HEAP_START = 0;
HEAP_SIZE = 0;
STACK_TOP = 0x04015fe0;
STACK_SIZE = 4096-BANK7_RESERVE;

Note: If both HEAP_START and HEAP_SIZE are 0, you can set HEAP_TOP. In this case, HEAP_TOP cannot be set to a region equal to or greater than 0x0402_0000.

  • To allocate 64KB for the HEAP from 0x0402_0000 and move the STACK area to a region below 0x04015fe0:
HEAP_START = 0x04020000;
HEAP_SIZE = 0x10000;
STACK_TOP = 0x04015fe0;
STACK_SIZE = 4096-BANK7_RESERVE;

OneTime_Heap.c,h

TWENETutils provides a One Time Heap for sequential memory allocation without deallocation. This makes it easy to use unused areas.

#include <OneTimeHeap.h>
OTHEAP_tsContext scOTHeap;

void setup() {
    uint32 u32bytes;
    void *p;

    // Use the 16KB region from 0x0402_0000 to 0x0402_4000.
    OTHEAP_Init(&scOTHeap, 0x04020000, 0x04024000, NULL);

    Serial << crlf << "--- One Time HEAP ---";
    Serial << crlf << format("start %08x", (uint32)OTHEAP_pvGetRegionStart(&scOTHeap));
    Serial << crlf << format("top %08x", (uint32)OTHEAP_pvGetRegionTop(&scOTHeap));

    // Allocate 100 bytes
    u32bytes = 100;
    Serial << crlf;
    Serial << crlf << format("head %08x", (uint32)OTHEAP_pvGetHead(&scOTHeap));
    p = OTHEAP_pvAlloc(&scOTHeap, u32bytes, TRUE);
    		// p=0x0402_0004 (The area after the 4-byte header is available)
    Serial << crlf << format("alloc %dbytes [%08x->%08x)", u32bytes, (uint32)p, (uint32)p+u32bytes);
    if(p) Serial << crlf << format("next %08x", *(uint32*)((uint32)p - 4));
    		// The header is the address of the next block (0x0402_0068)

    // Allocate 10 bytes (actually 12 bytes because it's aligned to a 4-byte boundary)
    u32bytes = 10;
    Serial << crlf;
    Serial << crlf << format("head %08x", (uint32)OTHEAP_pvGetHead(&scOTHeap));
    p = OTHEAP_pvAlloc(&scOTHeap, u32bytes, TRUE);
    		// p=0x0402_006c
    Serial << crlf << format("alloc %dbytes [%08x->%08x)", u32bytes, (uint32)p, (uint32)p+u32bytes);
    if(p) Serial << crlf << format("next %08x", *(uint32*)((uint32)p - 4));
    		// The header is the address of the next block (0x0402_0078)

    // Free the last allocated block. The address of the freed block (p=0x0402_006c)
    p = OTHEAP_pvFreeLastBlock(&scOTHeap);
}