ESP32-S3专题二:深入探讨RAM的使用方法

esp32-S3模块内部的存储分为ROM,RAM,SPRAM,RTC内存,FLASH,种类很多,几乎可以不使用外接存储器的情况下,可以进行很多业务场景,十分有用。现在我们逐一讲解一下他们的作用和使用方法。

一、ROM

384 KB 内部 ROM,
作用:ESP32技术手册明确说明:Internal ROM 是只读存储器,不可编程。Internal ROM 中存放有一些系统底层软件的 ROM 代码(程序指令和一些只读数据)。程序无法修改,暂不讨论。
关于ROM注意的是,全局的const变量和字符串常量通常会存放在只读数据区(.rodata),有一些硬件芯片会将这个数据区放在ROM里面,但是ESP32将数据区放置在RAM,区分清楚就好。

二、RAM

种类:片内SRAM +片外PSRAM

(一)片内SRAM:

大小:512 KB
关系:片内SRAM = IRAM (192KB ) + DRAM( 328KB )

IRAM :

作用:存储关键代码。
1.中断处理程序。注册中断处理程序时使用了 ESP_INTR_FLAG_IRAM,则中断处理程序必须要放入 IRAM。
2.可将一些时序关键代码放入 IRAM,以减少从 flash 中加载代码造成的相关损失。
3.以上两点为链接器自主操作,官方也提供接口,可以通过程序来声明函数,可以将 IRAM_ATTR 宏用作属性,直接将程序存储在这部分空间。(非芯片核心开发人员不推荐使用,容易触发芯片系统安全机制)

void IRAM_ATTR gpio_isr_handler(void* arg)
{
   const static DRAM_ATTR uint8_t INDEX_DATA[] = { 45, 33, 12, 0 };
   const static char *MSG = DRAM_STR("I am a string stored in RAM");
}

函数中的字符串或常量可能没有自动放入 RAM 中,这时可以使用 DRAM_ATTR 属性进行标记,或者也可以使用链接器脚本方法将它们自动放入 RAM 中。

DRAM:

作用两个:

  1. 非常量静态数据(.data 段)和零初始化数据(.bss 段)由链接器放入内部 SRAM 作为数据存储。
    这部分空间的使用是由链接器在对项目代码编译链接时,根据程序内容自动使用。空间大小随程序内部使用情况扩张。
  2. 官方也提供接口,可以通过程序声明变量,直接使用这部分空间。可以将 __NOINIT_ATTR 宏用作属性,从而将数据放入 .noinit 部分。放入该部分的值在启动时不会被初始化,在软件重启后也会保持值不变。
__NOINIT_ATTR uint32_t noinit_data;
  1. 此区域中的剩余空间可在程序运行时用作堆,也就是内部堆
    查看内部堆大小的函数:
printf("sp_get_free_internal_heap_size = %ld\n\r", esp_get_free_internal_heap_size());

一般打印完,发现内部堆大小只有200多KB,因为实际的内部堆大小只有RAM中的DRAM中的一部分,其最主要的作用是负责程序的运行空间,例如一般创建线程时声明的任务栈大小所需的空间就是直接从内部堆里面分配出去的。创建20k大小的线程,对应的内部堆就减少20k空间。

xTaskCreate((TaskFunction_t )task,"task", 20*1024, (void* )NULL,20,  (TaskHandle_t* )&ITask_Handler);

(二)片外PSRAM:

具体大小可根据使用业务进行配置,通常:2-8M
作用:提供更多空间,方便数据的存储和使用。

配置使用:

1.开启:使能Support for external,SPI-connected RAM
2.根据实际外置的PSRAM类型来选择:Quad 或者Octal
3.选择程序申请堆的API接口:可以选择2或者3。


(上图为2.9.1版ESP-IDE,部分旧版编辑器将此项类型ESPS3特殊设置或者ESP系统设置里面)

选型2:使用heap_caps_malloc()申请堆,灵活配置申请。

char *data=(char *) heap_caps_malloc(1024*sizeof(char), MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM);

配置项的意义:

/**
 * @brief Flags to indicate the capabilities of the various memory systems
 */
#define MALLOC_CAP_EXEC             (1<<0)  ///< Memory must be able to run executable code
#define MALLOC_CAP_32BIT            (1<<1)  ///< Memory must allow for aligned 32-bit data accesses
#define MALLOC_CAP_8BIT             (1<<2)  ///< Memory must allow for 8/16/...-bit data accesses
#define MALLOC_CAP_DMA              (1<<3)  ///< Memory must be able to accessed by DMA
#define MALLOC_CAP_PID2             (1<<4)  ///< Memory must be mapped to PID2 memory space (PIDs are not currently used)
#define MALLOC_CAP_PID3             (1<<5)  ///< Memory must be mapped to PID3 memory space (PIDs are not currently used)
#define MALLOC_CAP_PID4             (1<<6)  ///< Memory must be mapped to PID4 memory space (PIDs are not currently used)
#define MALLOC_CAP_PID5             (1<<7)  ///< Memory must be mapped to PID5 memory space (PIDs are not currently used)
#define MALLOC_CAP_PID6             (1<<8)  ///< Memory must be mapped to PID6 memory space (PIDs are not currently used)
#define MALLOC_CAP_PID7             (1<<9)  ///< Memory must be mapped to PID7 memory space (PIDs are not currently used)
#define MALLOC_CAP_SPIRAM           (1<<10) ///< Memory must be in SPI RAM
#define MALLOC_CAP_INTERNAL         (1<<11) ///< Memory must be internal; specifically it should not disappear when flash/spiram cache is switched off
#define MALLOC_CAP_DEFAULT          (1<<12) ///< Memory can be returned in a non-capability-specific memory allocation (e.g. malloc(), calloc()) call
#define MALLOC_CAP_IRAM_8BIT        (1<<13) ///< Memory must be in IRAM and allow unaligned access
#define MALLOC_CAP_RETENTION        (1<<14) ///< Memory must be able to accessed by retention DMA
#define MALLOC_CAP_RTCRAM           (1<<15) ///< Memory must be in RTC fast memory

#define MALLOC_CAP_INVALID          (1<<31) ///< Memory can't be used / list end marker

选型3:使用malloc方式申请最直接,默认使用malloc时向外部推申请空间。

 char *data=(char *)malloc(1024*sizeof(char));

另外,也可以通过API接口查看外部堆的剩余大小:

printf(".esp_get_free_heap_size = %d\n\r", esp_get_free_heap_size());

这次分享到处结束,下次分享给大家讲讲Cache、片上的flash和RTC存储器用法,觉得有帮助可以点个赞,谢谢大家。

参考:

https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/api-guides/memory-types.html#iram-ram
https://www.espressif.com.cn/sites/default/files/documentation/esp32-s3_technical_reference_manual_cn.pdf
https://blog.csdn.net/qq_41741344/article/details/116380816

物联沃分享整理
物联沃-IOTWORD物联网 » ESP32-S3专题二:深入探讨RAM的使用方法

发表评论