瑞芯微Rockchip开发者社区
直播中

刘洋

10年用户 1169经验值
擅长:可编程逻辑 嵌入式技术
私信 关注
[问答]

ESP32存储系统分为几部分呢

ESP32存储系统分为几部分呢?SPI flash的操作方法是怎样的?



回帖(1)

费晨

2022-1-14 10:53:15
1. ESP32 存储系统简介

ESP32 存储系统分为片上存储和片外存储。
其中片上存储包括:


  • 448 KB 的 ROM,用于程序启动和内核功能调用
  • 520 KB 片上 SRAM,用于数据和指令存储
  • RTC 快速存储器,为 8 KB 的 SRAM,可以在 Deep-sleep 模式下 RTC 启动时用于数据存储以及被主 CPU
    访问
  • RTC 慢速存储器,为 8 KB 的 SRAM,可以在 Deep-sleep 模式下被协处理器访问
  • 1 Kbit 的 eFuse,其中 256 bit 为系统专用(MAC 地址和芯片设置) ; 其余 768 bit 保留给用户程序, 这些程
    序包括 flash 加密和芯片 ID
  • 嵌入式 flash ESP32-D2WD带有16Mbit,40MHz的嵌入式flash,与GPIO16,GPIO17,SD_CMD,SD_CLK,SD_DATA_0和SD_DATA_1连接。

ESP32 支持多个外部 QSPI flash 和静态随机存储器 SRAM。外部 flash 可以同时映射到 CPU 指令和只读数据空间。外部 flash 最大可支持 16 MB。外部 SRAM 可映射到 CPU 数据空间。外部 SRAM 最大可支持 8 MB。一次最多可映射 4 MB。虽然 ESP32 能够支持多种类型的 RAM 芯片,但 ESP32_SDK 目前支持 ESP_PSRAM32、ESP_PSRAM64。在芯片启动后,用户程序可以 MAP 外部 SRAM 或 flash 到 CPU 地址空间。
2. 地址映射

ESP32 地址映射如下:
地址 0x4000_0000 以下的部分属于数据总线的地址范围;
地址 0x4000_0000~0x4FFF_FFFF 部分属于指令总线的地址范围;
地址 0x5000_0000 及以上的部分是数据总线和指令总线共用的地址范围。




3. SRAM 简析

静态随机存取存储器(Static Random-Access Memory,SRAM)
SRAM 分为 IRAM 和 DRAM:


  • IRAM 储存指令(程序)
  • DRAM 储存数据(堆等)

4. 软件支持的外部 RAM(External RAM)

ESP-IDF 完全支持在应用程序中使用外部 RAM,在启动时初始化外部 RAM,提供了多种方式来配置处理外部 RAM。
Initialize SPI RAM when booting the ESP32,即在 ESP32 boot 时初始化 SPI RAM。
方式1、整合 RAM 到 ESP32 内存映射。这是一个外部 RAM 的基本选项。外部 RAM 指向地址空间 0x3F800000(字节访问)。外部 RAM 的区域大小是 SPI RAM 大小(最大 4 MB)。通过指针指向外部 RAM 来放置数据。
方式2、初始化 RAM 并将其添加到功能分配器。这就允许程序使用
heap_caps_malloc(size,MALLOC_CAP_SPIRAM) 专门分配一块外部 RAM。可以使用该内存,然后使用正常的 free() 来释放。映射到 0x3F800000.
方式3、初始化 RAM,将其添加到功能分配器,并将内存添加到可由 malloc() 返回的 RAM 池中。 这允许任何应用程序使用外部 RAM 而无需重写代码以使用 heap_caps_malloc。这是默认。
方式4、允许在外部 RAM 放置 BSS 段,这段地址空间起始于 0x3F800000,用于 lwip、net80211、libpp 和 bluedroid ESP-IDF 库存储初始化为零的数据( bss 段)。通过在静态声明中应用 EXT_RAM_ATTR 宏(未初始化为 0 值)从内部 BSS 段移到外部 RAM。这有效减少 BSS 段使用的内部静态内存。
5. SPI flash 的操作方法

在 ESP-IDF 中定义已经好了 SPI flash 相关的操作函数了,我们在使用时只要按照要求初始化就可以调用相关 API 操作 flash 了。 使用方法:


void spi_flash_init();//flash 初始化在使用 spi-flash 之前需要调用此函数进行初始化。size_t spi_flash_get_chip_size();//获取当前 flash 的容量大小。/*按照扇区擦除 flash,sector 为扇区号*/esp_err_t spi_flash_erase_sector(size_t sector);/*按照地址擦除 flash,start_address 擦除的起始地址,size 是擦除大小,地址必须是 4 的倍数*/esp_err_t spi_flash_erase_range(size_t start_address, size_t size);/*将数据写入 flash,dest_addr flash 首地址,src 是要写入数据的首地址,size 是 src 数据的大小*/esp_err_t spi_flash_write(size_t dest_addr, const void *src, size_t size);/*从 flash 中读出数据,src_addr 是要 flash, dest 是接收数据的首地址,size 是读取的大小*/esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size);




如果在调用 flash 期间调用中断,则需要在函数前面加上 IARM_ATTR 属性
#include "esp_attr.h"void IRAM_ATTR gpio_isr_handler(void* arg){    // ...}




为常量添加DRAM_ATTR和DRAM_STR 属性
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");}




6. 分区表简介

ESP-IDF 工程使用分区表保存 SPI flash 各区信息,包括引导程序、各种应用程序二进制文件、数据及文件系统等。 分区表相关介绍参考 ESP32 分区表
7. 非易失性存储库(NVS)

非易失性存储 (NVS) 库主要用于在 flash 中存储键值格式的数据。具体请参考 ESP32 非易失性存储库
举报

更多回帖

发帖
×
20
完善资料,
赚取积分