这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » [ESP-IDF]使用ESP32-S31运行LVGLbenchmark

共2条 1/1 1 跳转至

[ESP-IDF]使用ESP32-S31运行LVGLbenchmark

高工
2026-07-17 14:51:41     打赏

简介

ESP32-S31-Korvo-1 是一块偏向智能语音和图形界面开发的多媒体开发板,搭载双核 320 MHz RISC-V 架构的 ESP32-S31,并配有 16 MB Flash、16 MB PSRAM、双麦克风、扬声器输出、MicroSD 卡槽,以及 LCD 和摄像头接口。相比常见的 ESP32-S3,ESP32-S31 的主频从 240 MHz 提升到 320 MHz,处理器也从双核 Xtensa LX7 升级为带 SIMD 加速能力的 RISC-V 核心,同时支持更快的外部内存和 Wi-Fi 6,因此在界面绘制、图片解码、语音处理和多任务运行方面理论上会更强。在接下来的文章中我将会在Korvo1上运行LVGL的benchmark来间接的测试性能。


ESP32-S31-Korvo-1 V1.1(板载 ESP32-S31-WROOM-3 模组)

这个屏幕是4.3寸,因此在这个板子上运行LVGL的benchmark 还是稍微有一点压力的。


1 - 准备工作

首先创建一个空的project,然后在组件管理器中将下述的依赖加入到当前的项目中

espressif/esp32_s31_korvo_1: ^1.0.0~1
  lvgl/lvgl: ^9.5.0

完整的idf_component.yml如下所示

## IDF Component Manager Manifest File
dependencies:
  ## Required IDF version
  idf:
    version: '>=4.1.0'
  # # Put list of dependencies here
  # # For components maintained by Espressif:
  # component: "~1.0.0"
  # # For 3rd party components:
  # username/component: ">=1.0.0,<2.0.0"
  # username2/component2:
  #   version: "~1.0.0"
  #   # For transient dependencies `public` flag can be set.
  #   # `public` flag doesn't have an effect dependencies of the `main` component.
  #   # All dependencies of `main` are public by default.
  #   public: true
  espressif/esp32_s31_korvo_1: ^1.0.0~1
  lvgl/lvgl: ^9.5.0

之后构建一次项目,组件管理器便会自动的将对应的依赖下载到本地。

image.png2- 下载完成之后可以打开Lvgl的库,其中里面有我们需要运行的demo

image.png3- 在menuconfig中开启psram

image.png这里主要的作用是为了避免LVGL占用大量的内存的情况, S31的内置ram并不是很大,所以要将对应的数据划分到PSRAM中。虽然牺牲了部分的速度但是程序的运行得到了保障。

4-主程序代码

/*
 * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include "esp_log.h"
#include "bsp/esp-bsp.h"
#include "lv_demos.h"

static const char *TAG = "LVGL Benchmark";

static void benchmark_end_cb(const lv_demo_benchmark_summary_t *summary)
{
    ESP_LOGI(TAG, "=== Benchmark Summary ===");
    ESP_LOGI(TAG, "Total avg FPS: %ld", (long)summary->total_avg_fps);
    ESP_LOGI(TAG, "Total avg CPU: %ld%%", (long)summary->total_avg_cpu);
    ESP_LOGI(TAG, "Total avg render time: %ld ms", (long)summary->total_avg_render_time);
    ESP_LOGI(TAG, "Total avg flush time: %ld ms", (long)summary->total_avg_flush_time);
    ESP_LOGI(TAG, "Valid scenes: %ld", (long)summary->valid_scene_cnt);

    for (int i = 0; summary->scenes[i].create_cb != NULL; i++) {
        const lv_demo_benchmark_scene_dsc_t *s = &summary->scenes[i];
        if (s->measurement_cnt > 0) {
            ESP_LOGI(TAG, "  Scene %d (%s): FPS=%lu, render=%lums, flush=%lums",
                     i, s->name,
                     (unsigned long)s->fps_avg,
                     (unsigned long)s->render_avg_time,
                     (unsigned long)s->flush_avg_time);
        }
    }
}

void app_main(void)
{
    ESP_LOGI(TAG, "Starting LVGL Benchmark demo on ESP32-S31-Korvo-1");

    /* Initialize BSP display with LVGL (use PSRAM for draw buffers) */
    bsp_display_cfg_t cfg = {
        .lvgl_port_cfg = {
            .task_priority = 5,
            .task_stack = 10240,
            .task_affinity = 1,
            .task_max_sleep_ms = 1,
            .task_stack_caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT,
            .timer_period_ms = 2,
        },
        .buffer_size = BSP_LCD_H_RES * CONFIG_BSP_LCD_DRAW_BUF_HEIGHT,
#if CONFIG_BSP_LCD_DRAW_BUF_DOUBLE
        .double_buffer = 1,
#else
        .double_buffer = 0,
#endif
        .flags = {
            .buff_dma = true,
            .buff_spiram = true,
            .sw_rotate = false,
        }
    };
    lv_display_t *disp = bsp_display_start_with_config(&cfg);
    if (disp == NULL) {
        ESP_LOGE(TAG, "Failed to start BSP display!");
        return;
    }

    /* Turn on display backlight */
    bsp_display_backlight_on();

    /* Lock LVGL mutex before calling LVGL APIs */
    bsp_display_lock(0);

    /* Set benchmark end callback for logging results */
    lv_demo_benchmark_set_end_cb(benchmark_end_cb);

    /* Run LVGL benchmark demo */
    lv_demo_benchmark();

    /* Release LVGL mutex */
    bsp_display_unlock();

    ESP_LOGI(TAG, "Benchmark demo started, results will be printed on completion");
}

主程序代码比较简单,benchmark的demo已经有了我们需要的只是在主程序中进行调用即可。

最后还有一点就是不要忘记加入LVGL porting的组件依赖。

idf_component_register(SRCS "hello_world_main.c"
                       PRIV_REQUIRES esp_lcd esp_lvgl_port
                       INCLUDE_DIRS "")

还有一点需要注意的是,上述初始化LVGL的时候已经将内存区域分配到了PSRAM中,如下代码所示

 bsp_display_cfg_t cfg = {
        .lvgl_port_cfg = {
            .task_priority = 5,
            .task_stack = 10240,
            .task_affinity = 1,
            .task_max_sleep_ms = 1,
            .task_stack_caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT,
            .timer_period_ms = 2,
        },
        .buffer_size = BSP_LCD_H_RES * CONFIG_BSP_LCD_DRAW_BUF_HEIGHT,
#if CONFIG_BSP_LCD_DRAW_BUF_DOUBLE
        .double_buffer = 1,
#else
        .double_buffer = 0,
#endif
        .flags = {
            .buff_dma = true,
            .buff_spiram = true,
            .sw_rotate = false,
        }
    };

重要的参数如下MALLOC_CAP_SPIRAM , 即将内存划分到SPI RAM中,然后将程序进行编译和烧录。如下所示

image.png

效果视频如下所示:实际测试下来在复杂的场景下帧率在8FPS左右,正常的场景在15FPS左右,静态的图片在40FPS左右。暂时不清楚还有什么其他的优化措施来增加帧率。




关键词: ESP-IDF     ESP32-S31     benchma    

专家
2026-07-18 07:00:53     打赏
2楼

谢谢楼主分享


共2条 1/1 1 跳转至

回复

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