feat(jpeg): support jpeg sleep retention on esp32p4

This commit is contained in:
C.S.M
2026-03-23 11:18:23 +08:00
committed by BOT
parent b4424ddf4d
commit cb7c429747
17 changed files with 267 additions and 11 deletions
@@ -5,6 +5,9 @@ if(CONFIG_SOC_JPEG_DECODE_SUPPORTED)
list(APPEND srcs
"test_jpeg_decode.c"
)
if(CONFIG_PM_ENABLE)
list(APPEND srcs "test_jpeg_sleep_retention.c")
endif()
endif()
if(CONFIG_SOC_JPEG_ENCODE_SUPPORTED)
@@ -14,5 +17,5 @@ if(CONFIG_SOC_JPEG_ENCODE_SUPPORTED)
endif()
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES esp_driver_jpeg unity esp_psram test_utils
PRIV_REQUIRES esp_driver_jpeg unity esp_psram test_utils esp_pm
WHOLE_ARCHIVE)
@@ -11,7 +11,7 @@
// Some resources are lazy allocated in JPEG driver, so we reserved this threshold when checking memory leak
// A better way to check a potential memory leak is running a same case by twice, for the second time, the memory usage delta should be zero
#define LEAKS (400)
#define LEAKS (500)
void setUp(void)
{
@@ -0,0 +1,99 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "unity.h"
#include "test_utils.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "esp_private/periph_ctrl.h"
#include "driver/jpeg_decode.h"
#include "esp_log.h"
#include "test_jpeg_performance.h"
#include "esp_system.h"
#include "ccomp_timer.h"
#include "esp_sleep.h"
#include "esp_private/sleep_cpu.h"
#include "esp_pm.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_pmu.h"
extern const uint8_t image_esp1080_jpg_start[] asm("_binary_esp1080_jpg_start");
extern const uint8_t image_esp1080_jpg_end[] asm("_binary_esp1080_jpg_end");
#if SOC_LIGHT_SLEEP_SUPPORTED && CONFIG_PM_ENABLE
static void test_jpeg_sleep_retention(bool allow_pd)
{
jpeg_decoder_handle_t jpgd_handle;
jpeg_decode_engine_cfg_t decode_eng_cfg = {
.intr_priority = 0,
.timeout_ms = 40,
.flags = {
.allow_pd = allow_pd,
},
};
jpeg_decode_cfg_t decode_cfg = {
.output_format = JPEG_DECODE_OUT_FORMAT_RGB565,
};
jpeg_decode_memory_alloc_cfg_t rx_mem_cfg = {
.buffer_direction = JPEG_DEC_ALLOC_OUTPUT_BUFFER,
};
jpeg_decode_memory_alloc_cfg_t tx_mem_cfg = {
.buffer_direction = JPEG_DEC_ALLOC_INPUT_BUFFER,
};
size_t rx_buffer_size;
uint8_t *rx_buf_1080p = (uint8_t*)jpeg_alloc_decoder_mem(1080 * 1920 * 3, &rx_mem_cfg, &rx_buffer_size);
uint32_t out_size_1080p = 0;
size_t bit_stream_length = (size_t)image_esp1080_jpg_end - (size_t)image_esp1080_jpg_start;
size_t tx_buffer_size;
uint8_t *tx_buf_1080p = (uint8_t*)jpeg_alloc_decoder_mem(bit_stream_length, &tx_mem_cfg, &tx_buffer_size);
// Copy bit stream to psram
memcpy(tx_buf_1080p, image_esp1080_jpg_start, bit_stream_length);
TEST_ESP_OK(jpeg_new_decoder_engine(&decode_eng_cfg, &jpgd_handle));
TEST_ESP_OK(jpeg_decoder_process(jpgd_handle, &decode_cfg, tx_buf_1080p, bit_stream_length, rx_buf_1080p, rx_buffer_size, &out_size_1080p));
esp_sleep_context_t sleep_ctx;
esp_sleep_set_sleep_context(&sleep_ctx);
#if CONFIG_PM_ESP_SLEEP_POWER_DOWN_CPU
TEST_ESP_OK(sleep_cpu_configure(true));
#endif
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(2 * 1000 * 1000));
TEST_ESP_OK(esp_light_sleep_start());
#if CONFIG_PM_ESP_SLEEP_POWER_DOWN_CPU
TEST_ESP_OK(sleep_cpu_configure(false));
#endif
printf("check if the sleep happened as expected\r\n");
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
// check if the power domain also is powered down
TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP);
TEST_ESP_OK(jpeg_decoder_process(jpgd_handle, &decode_cfg, tx_buf_1080p, bit_stream_length, rx_buf_1080p, rx_buffer_size, &out_size_1080p));
free(rx_buf_1080p);
free(tx_buf_1080p);
esp_sleep_set_sleep_context(NULL);
TEST_ESP_OK(jpeg_del_decoder_engine(jpgd_handle));
}
TEST_CASE("jpeg sleep retention test", "[jpeg]")
{
test_jpeg_sleep_retention(false);
test_jpeg_sleep_retention(true);
}
#endif
@@ -1,5 +1,6 @@
CONFIG_PM_ENABLE=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
CONFIG_PM_DFS_INIT_AUTO=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
@@ -1,5 +1,5 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n
CONFIG_ESP_TASK_WDT_EN=n
# SPIRAM configurations
@@ -13,3 +13,6 @@ CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# primitives for checking sleep internal state
CONFIG_ESP_SLEEP_DEBUG=y