IC:

RAM 布局与配置

简介

本章介绍默认内存布局及其修改方法。

RAM 内存布局

芯片集成了内部 SRAM 和可扩展的 PSRAM,其容量如下:

  • 内部 SRAM: 512KB

  • 可扩展的 PSRAM: 容量请参考 datasheet

../../rst_rtos/0_memory_layout/figures/ram_layout_512RAM.svg

SRAM 与 PSRAM 混合布局

../../rst_rtos/0_memory_layout/figures/ram_layout_with_psram_dplus.svg

Item

起始地址

大小 (KB)

描述

必需

SRAM FIXED

0x2000_0000

40

用于 ROM BSS, MSP 等

KM4 Bootloader

0x3000_A000

32

KM4 安全启动加载程序,包括代码和数据

KM4 BD RAM TZ

0x2001_2000

64

KM4 IMG3 BD RAM,如果不需要可以合并到 KM4 BD RAM

x

KM4 BD RAM

0x2002_2000

280

KM4 BDRAM 数据、BSS 和 heap

KM0 BD RAM

0x2006_8000

96

KM0 BDRAM 数据、BSS 和 heap

KM4 BD PSRAM TZ

0x6000_0000

64

KM4 IMG3 PSRAM,如果不需要可以合并到 KM4 PSRAM

x

KM4 BD PSRAM

0x6001_0000

3220

KM4 BD PSRAM 代码和数据

KM0 BD PSRAM

0x6032_5000

876

KM0 BD PSRAM 代码和数据

KM4 HEAP EXT

0x6FFF_FFFF

0

如果 KM4 堆空间不足,可用于扩展 heap 大小

x

KM0 HEAP EXT

0x6FFF_FFFF

0

如果 KM0 堆空间不足,可用于扩展 heap 大小

x

备注

如果 Trustzone 未启用,则 KM4 BD RAM TZKM4 BD PSRAM TZ 将作为 Non-secure 区域,并分别合并到 KM4 BD RAMKM4 BD PSRAM 中。

Bootloader_RAM

ameba_layout.ld 有如下定义:

#if defined(CONFIG_IMG1_FLASH)
   #define KM4_IMG1_SIZE                          KBYTES(4)
#else
   #define KM4_IMG1_SIZE                          KBYTES(32)
#endif

KM4_BOOTLOADER_RAM_S (rwx) :            ORIGIN = KM4_IMG1_RAM_SATRT + SECURE_ADDR_OFFSET + IMAGE_HEADER_LEN, LENGTH = KM4_IMG1_SIZE  - IMAGE_HEADER_LEN

在 menuconfig 中配置 CONFIG Link Option 选项, bootloader 占用 RAM 空间会随之调整:

  • 选择 IMG1 –> FLASH 时, KM4_BOOTLOADER_RAM_S 预设为 4KB

  • 选择 IMG1 –> SARM 时, KM4_BOOTLOADER_RAM_S 预设为 32KB

如需扩大 KM4_BOOTLOADER_RAM_S ,需确保调整后的尺寸为 4KB 对齐(MPC 保护以 4KB 为单位)。

BD_RAM 和 BD_PSRAM

BD_RAM

ameba_layout.ld 中有如下定义:

#define RAM_KM4_IMG3_SIZE           KBYTES(44)
#define RAM_KM0_IMG2_SIZE           KBYTES(96)
#define KM4_IMG2_RAM_START          (KM4_RAM_TZ_SECURE_START + RAM_KM4_IMG3_SIZE)
#define KM0_IMG2_RAM_START          (SRAM_END - RAM_KM0_IMG2_SIZE)

KM4_BD_RAM (rwx) :                  ORIGIN = KM4_IMG2_RAM_START + IMAGE_HEADER_LEN,       LENGTH = KM0_IMG2_RAM_START - KM4_IMG2_RAM_START - IMAGE_HEADER_LEN
KM0_BD_RAM (rwx) :                  ORIGIN = KM0_IMG2_RAM_START + IMAGE_HEADER_LEN,       LENGTH = RAM_KM0_IMG2_SIZE - IMAGE_HEADER_LEN
  • 除 Fixed RAM 以及 IMG1 所占用空间外,剩余的 SRAM 空间分配给 KM4_IMG3, KM0_IMG2, 以及 KM4_IMG2。 ameba_layout.ld 中已通过 RAM_KM4_IMG3_SIZE 定义 KM4_IMG3 占用的 SRAM 空间大小,通过 RAM_KM0_IMG2_SIZE 定义 KM0_IMG2 占用的 SRAM 大小,剩余的空间用作 KM4_IMG2,用户可以根据实际需求调整相应的值。

BD_PSRAM

ameba_layout.ld 中有如下定义:

#define PSRAM_BASE                  (0x60000000)
#define PSRAM_END                   (0x60400000)
#define PSRAM_KM4_IMG3_SIZE         KBYTES(44)
#define PSRAM_KM4_IMG2_SIZE         (KBYTES(3220) - (PSRAM_TZ_NSC_SIZE + PSRAM_TZ_ENTRY_SIZE + PSRAM_KM4_IMG3_SIZE))
#define KM4_IMG2_PSRAM_START        (KM4_PSRAM_TZ_SECURE_START + PSRAM_KM4_IMG3_SIZE)
#define KM0_IMG2_PSRAM_START        (KM4_IMG2_PSRAM_START + PSRAM_KM4_IMG2_SIZE)
#define PSRAM_KM0_IMG2_SIZE         (PSRAM_END - KM0_IMG2_PSRAM_START)

KM4_BD_PSRAM (rwx) :                ORIGIN = KM4_IMG2_PSRAM_START + IMAGE_HEADER_LEN,  LENGTH = PSRAM_KM4_IMG2_SIZE - IMAGE_HEADER_LEN
KM0_BD_PSRAM (rwx) :                ORIGIN = KM0_IMG2_PSRAM_START + IMAGE_HEADER_LEN,  LENGTH = PSRAM_KM0_IMG2_SIZE - IMAGE_HEADER_LEN
  • PSRAM 的空间依次分配给 KM4_IMG3, KM4_IMG2, KM0_IMG2,PSRAM 的起始和结束地址分别由 PSRAM_BASEPSRAM_END 定义,默认大小为 4MB。 起始地址 PSRAM_BASE 为固定值,用户可根据实际 PSRAM 大小调整结束地址 PSRAM_END 的值 。

  • 如需调整 PSRAM_BASEPSRAM_END 之间的空间分配,请通过 PSRAM_KM4_IMG3_SIZE 调整 KM4_IMG3 的大小,通过 PSRAM_KM4_IMG2_SIZE 调整 KM4_IMG2 的大小,剩余的空间将全部分配给 KM0_IMG2。

  • PSRAM_END 之后的空间(如有)可作为拓展 heap xxx_PSRAM_HEAP_EXT 使用,默认未启用。

堆内存(Heap)

调整 HEAP 大小

  1. BD_RAM 和 BD_PSRAM 加载完静态区域后的剩余空间都将作为 heap 使用,因此可通过调整 BD_RAM 和 BD_PSRAM 的区域来扩大或缩小对应 MCU 的 heap 空间,调整方法参考 BD_RAM 和 BD_PSRAM

  2. 将空闲的 PSRAM 地址定义到 xxx_PSRAM_HEAP_EXT 以使能 PSRAM_HEAP_EXT 区域:

    默认的 PSRAM_HEAP_EXT 的区域为无效值:

    xxx_PSRAM_HEAP_EXT (rwx) :              ORIGIN = 0x6FFFFFFF, LENGTH = 0x6FFFFFFF - 0x6FFFFFFF     /* PSRAM HEAP EXT */
    

    可以将空闲的 PSARM 区域(如存在, 以 0x60400000 ~ 0x60800000 为例)定义到:

    xxx_PSRAM_HEAP_EXT (rwx) :              ORIGIN = 0x60400000, LENGTH = 0x60800000 - 0x60400000     /* PSRAM HEAP EXT */
    

备注

  • 可以在 xxx_gcc_project/project_xx/xsdk/image/target_img2.map 中查看 __bdram_heap_buffer_size__, __psram_heap_buffer_size__, __psram_heap_extend_size__ 来获取对应 HEAP 区域的实际空间。

  • 当 menuconfig 选中 ALL PSRAM USED FOR APPLICATION HEAP 时, PSARM_BDRAM 与 PSRAM_HEAP_EXT 的定义无效,PSRAM 的整个区域将直接划分给 application 的 heap 使用。

API 参考

MALLOC_TYPES

typedef enum {
   TYPE_TCM = 0,
   TYPE_SRAM,
   TYPE_DRAM,
   TYPE_ALL
} MALLOC_TYPES;

内存类型:

TYPE_TCM:

可从 TCM, SRAM, DRAM 类型的内存中申请(如有), 即可以申请从 0x00000000 开始的内存地址。

TYPE_SRAM:

不可从 TCM 中申请内存,仅可从 SRAM, DRAM 中申请(如有),即可以申请从 0x20000000 开始的内存地址。

TYPE_DRAM:

不可从 TCM,SRAM 中申请内存,仅可从 DRAM 中申请(如有),即可以申请从 0x60000000 开始的内存地址。

TYPE_ALL:

无限制,可以申请从 0x00000000 开始的内存地址。

malloc

void *rtos_mem_malloc(uint32_t size);

从初始化好的 heap 区域中申请一块内存空间,无内存类型限制。

  • 参数:

    size:

    申请内存块的大小

  • 返回值: 指向内存块起始地址的指针

void *rtos_heap_types_malloc(uint32_t size, MALLOC_TYPES type);

从初始化好的 heap 区域中申请一块内存空间,仅可申请指定内存类型的内存块。

  • 参数:

    size:

    申请内存块的大小

    type:

    内存类型

  • 返回值: 指向内存块起始地址的指针

zmalloc

void *rtos_mem_zmalloc(uint32_t size);

从初始化好的 heap 区域中申请一块内存空间,并将分配的内存初始化为 0。无内存类型限制。

  • 参数:

    size:

    申请内存块的大小

  • 返回值: 指向内存块起始地址的指针

void *rtos_heap_types_zmalloc(uint32_t size, MALLOC_TYPES type);

从初始化好的 heap 区域中申请一块内存空间,并将分配的内存初始化为 0。仅可申请指定内存类型的内存块。

  • 参数:

    size:

    申请内存块的大小

    type:

    内存类型

  • 返回值: 指向内存块起始地址的指针

calloc

void *rtos_mem_calloc(uint32_t elementNum, uint32_t elementSize);

从初始化好的 heap 区域中申请一块内存空间,用于存储 num 个大小为 size 的元素,并将分配的内存初始化为 0。无内存类型限制。

  • 参数:

    elementNum:

    元素数量

    elementSize:

    单个元素的大小

  • 返回值: 指向内存块起始地址的指针

void *rtos_heap_types_calloc(uint32_t elementNum, uint32_t elementSize, MALLOC_TYPES type);

从初始化好的 heap 区域中申请一块内存空间,用于存储 num 个大小为 size 的元素,并将分配的内存初始化为 0。仅可申请指定内存类型的内存块。

  • 参数:

    elementNum:

    元素数量

    elementSize:

    单个元素的大小

    type:

    内存类型

  • 返回值: 指向内存块起始地址的指针

realloc

void *rtos_mem_realloc(void *ptr, uint32_t new_size);

调整之前分配的内存块的大小。如果新的内存块大于原内存块,新增部分的内容不会被初始化。若无法在原位置扩展,则会尝试移动整个内存块到新位置并释放旧内存。无内存类型限制。

  • 参数:

    ptr:

    指向已分配内存块的指针

    new_size:

    新的内存块大小

  • 返回值: 指向重新分配后的内存块起始地址的指针,失败时返回 NULL(原始内存未释放)

void *rtos_heap_types_realloc(void *ptr, uint32_t new_size, MALLOC_TYPES type);

调整之前分配的内存块的大小。如果新的内存块大于原内存块,新增部分的内容不会被初始化。若无法在原位置扩展,则会尝试移动整个内存块到新位置并释放旧内存。仅可申请指定内存类型的内存块。

  • 参数:

    ptr:

    指向已分配内存块的指针

    new_size:

    新的内存块大小

    type:

    内存类型

  • 返回值: 指向重新分配后的内存块起始地址的指针,失败时返回 NULL(原始内存未释放)

free

void rtos_mem_free(void *pbuf);

void rtos_heap_types_free(void *pbuf);

释放内存块。

  • 参数:

    pbuf:

    指向带释放内存块起始地址的指针

  • 返回值: 无