简介
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来间接的测试性能。

这个屏幕是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
之后构建一次项目,组件管理器便会自动的将对应的依赖下载到本地。
2- 下载完成之后可以打开Lvgl的库,其中里面有我们需要运行的demo
3- 在menuconfig中开启psram
这里主要的作用是为了避免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中,然后将程序进行编译和烧录。如下所示

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