这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【ESP-IDF系列】【ESP32】ESP32-S3PSRAM读写测试+通用定时

共1条 1/1 1 跳转至

【ESP-IDF系列】【ESP32】ESP32-S3PSRAM读写测试+通用定时器

助工
2025-02-26 09:51:19     打赏

简介

在前几个esp32系列的帖子中, 我使用的是一块esp32s3-n4的开发板,它使用4MB的flash并没有psram. 为了这个帖子我又购买了一块esp32s3n8r8的模组来做psram的读写测试. 开发板如下图所示. 其他功能和之前的开发板一致.

image.png

PSRAM简介

PSRAM(Pseudo Static Random Access Memory)是一种伪静态随机存取存储器,结合了 DRAM 的高密度和 SRAM 的易用性。ESP32-S3 N8R8 内置了 8MB PSRAM,型号中的 "N8R8" 表示 8MB Flash 和 8MB PSRAM。支持高达 120MHz 的时钟频率,满足实时数据处理需求(官方推荐配置为80MHZ)。

本章节的主要内容为探讨如何配置和使用psram, 以及通过通用定时器,对psram进行读写测试. 要使用PSRAM首先我们需要在menuconfig中使能psram. 否则就算模组是n8r8, psram仍然处于不可用的状态.

image.png

首先使能PSRAM, 然后配置PSRAM的模式为8线PSRAM, 动态检测PSRAM大小, 以及默认的频率配置. 同时把所有的指令从flash移动到PSRAM中以及把所有的只读数据移动到psram中. 同时还可以选择PSRAM的访问方式. 我这里设置的是允许使用malloc函数来分配内存到psram里.

image.png

其他的数据保持默认,至此PSRAM的配置已经完成了. 接着将程序编译,然后烧录到开发板中.

image.png

我们可以通过监视的日志打印查看到PSRAM已经挂载和识别完毕. 大小为8000K, 即8MB(计量不同, 非1024 * 1024 * 8)

此时我们便可以使用malloc函数来分配内存从PSRAM里. 如下代码所示

size_t size_to_allocate = 1000 * 1000 * 8;
void *external_ram_ptr = malloc(size_to_allocate);
if (external_ram_ptr == NULL)
{
    printf("Failed to allocate memory using malloc!\n");
    return;
}

但是只有内存的分配,我们并不清楚实际的PSRAM的读写速度. 我们可以借助ESP32的通用定时器来实现这个功能. 首先,我们引入通用定时器的头文件, 然后来初始化一个通用定时器的结构体.

gptimer_config_t timer_config = {
    .clk_src = GPTIMER_CLK_SRC_DEFAULT,
    .direction = GPTIMER_COUNT_UP,
    .resolution_hz = 1 * 1000 * 1000, // 1MHz, 1 tick = 1us
    };
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));

其中配置,使用默认的时钟源, 计时器为向上计数, 分辨率为 1MHZ 即每一个counter为1us. 这样的话我们只需要在分配完毕内存的时候,载向PSRAM读取之前,开启定时器, 然后写入之后读取一次定时器的值即为写入的耗时,然后在读取完毕之后再读取一次定时器的值. 使用第二次定时器的值减去第一次定时器的值即为读取的时间.

void psram_test()
{
    ESP_ERROR_CHECK(gptimer_enable(gptimer));
    ESP_ERROR_CHECK(gptimer_start(gptimer));

    uint64_t start_count, end_count;

    // 1. 分配片外 RAM
    size_t size_to_allocate = 1000 * 1000 * 8;
    void *external_ram_ptr = malloc(size_to_allocate);

    if (external_ram_ptr == NULL)
    {
        printf("Failed to allocate memory using malloc!\n");
        return;
    }

    printf("Successfully allocated %d bytes using malloc at address: %p\n", size_to_allocate, external_ram_ptr);

    // 2. 测量写入时间
    ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &start_count));
    int *data_array = (int *)external_ram_ptr;
    for (int i = 0; i < size_to_allocate / sizeof(int); i++)
    {
        data_array[i] = i; // 填充数据
    }
    ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &end_count));
    printf("Writing finished!\n");
    printf("Time used for writing: %lld us\n", end_count - start_count);

    // 3. 测量读取时间
    ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &start_count));
    volatile int *volatile_data_array = (volatile int *)external_ram_ptr;
    for (int i = 0; i < size_to_allocate / sizeof(int); i++)
    {
        volatile int value = volatile_data_array[i]; // 读取数据
        (void)value;                                 // 防止编译器优化掉读取操作
    }
    ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &end_count));
    printf("Reading finished!\n");
    printf("Time used for reading: %lld us\n", end_count - start_count);

    // 4. 释放内存
    free(external_ram_ptr);
    printf("Memory freed.\n");
}

此时便可以准确的计算出PSRAM的操作时间, 如下图所示.

image.png实际上可以看到读写速度还是超级快的, 8MB的PSRAM,写入的时间在237MS左右, 而读取的速度为300MS左右(不完全准确,但是已经可以看出来PSRAM的读写速度是非常快的了).


附件如下:

esp32-s3-PSRAM.zip




关键词: ESP-IDF     ESP32-S3          PSRAM         

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]