mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
feat(spi_flash): implement dynamic CPU frequency switching workaround for encrypted writes
This commit implements a workaround that allows ESP32-C5 to run at 240MHz CPU frequency normally, while automatically reducing CPU frequency during encrypted flash writes to ensure correct operation. The frequency limit is chip revision dependent: - v1.2 and above: limited to 160MHz during encrypted writes - v1.0 and below: limited to 80MHz during encrypted writes Key implementation details: - Frequency limiting is triggered automatically when esp_flash_write_encrypted() is called - Uses start() flags (ESP_FLASH_START_FLAG_LIMIT_CPU_FREQ) to integrate with OS layer - Works with both PM enabled and disabled configurations - Frequency is automatically restored after encrypted write completes - For ESP32-C5 with 120MHz flash, Flash clock and timing registers are adjusted when CPU frequency is reduced to 80MHz - SPI1 timing registers are configured during frequency switching since encrypted writes use SPI1 and must work correctly at reduced CPU frequencies Code improvements: - Use SOC_MSPI_FREQ_AXI_CONSTRAINED capability macro instead of hardcoded chip checks - Control workaround via Kconfig (CONFIG_PM_WORKAROUND_FREQ_LIMIT_ENABLED) instead of hardcoded macros - Add comprehensive test cases covering various PM configurations and edge cases This workaround enables ESP32-C5 applications to benefit from 240MHz CPU performance while maintaining reliable encrypted flash write functionality.
This commit is contained in:
@@ -15,6 +15,15 @@ components/spi_flash/test_apps/esp_flash:
|
||||
- esp_driver_spi
|
||||
- esptool_py # Some flash related kconfigs are listed here.
|
||||
|
||||
components/spi_flash/test_apps/esp_flash_freq_limit:
|
||||
enable:
|
||||
- if: IDF_TARGET == "esp32c5"
|
||||
depends_components:
|
||||
- spi_flash
|
||||
- esp_pm
|
||||
- esp_driver_gptimer
|
||||
- esp_hw_support
|
||||
|
||||
components/spi_flash/test_apps/esp_flash_stress:
|
||||
disable:
|
||||
- if: IDF_TARGET == "esp32h4"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on. We also depend on
|
||||
# esptool_py as we set CONFIG_ESPTOOLPY_... options.
|
||||
set(COMPONENTS main esptool_py)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
project(test_esp_flash_freq_limit)
|
||||
|
||||
message(STATUS "Checking memspi registers are not read-write by half-word")
|
||||
include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake)
|
||||
check_register_rw_half_word(SOC_MODULES "spi_mem*" "spi1_mem*"
|
||||
HAL_MODULES "spimem_flash")
|
||||
@@ -0,0 +1,2 @@
|
||||
| Supported Targets | ESP32-C5 |
|
||||
| ----------------- | -------- |
|
||||
@@ -0,0 +1,9 @@
|
||||
set(srcs "test_app_main.c"
|
||||
"test_esp_flash_freq_limit.c")
|
||||
|
||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(SRCS ${srcs}
|
||||
PRIV_REQUIRES unity test_utils spi_flash esp_pm bootloader_support freertos esp_timer
|
||||
esp_driver_gptimer esp_hw_support esp_psram
|
||||
WHOLE_ARCHIVE)
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_utils.h"
|
||||
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (700)
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
unity_utils_record_free_mem();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
unity_run_menu();
|
||||
}
|
||||
+1250
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
factory, 0, 0, 0x10000, 1M
|
||||
flash_test, data, fat, , 700K
|
||||
|
@@ -0,0 +1,23 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'pm_disabled_240mhz',
|
||||
'pm_disabled_160mhz',
|
||||
'pm_enabled_240mhz',
|
||||
'pm_enabled_160mhz',
|
||||
'pm_disabled_240mhz_xip_psram',
|
||||
'pm_enabled_240mhz_xip_psram',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['esp32c5'], indirect=['target'])
|
||||
def test_esp_flash_freq_limit(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(group='esp_flash_freq_limit', timeout=10)
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_PM_ENABLE=n
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_PM_ENABLE=n
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
CONFIG_PM_ENABLE=n
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_BOOT_HW_INIT=y
|
||||
CONFIG_SPIRAM_BOOT_INIT=y
|
||||
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
|
||||
CONFIG_SPIRAM_SPEED_120M=y
|
||||
@@ -0,0 +1,6 @@
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y
|
||||
@@ -0,0 +1,6 @@
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_BOOT_HW_INIT=y
|
||||
CONFIG_SPIRAM_BOOT_INIT=y
|
||||
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
|
||||
CONFIG_SPIRAM_SPEED_120M=y
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_BOOT_HW_INIT=y
|
||||
CONFIG_SPIRAM_BOOT_INIT=y
|
||||
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
|
||||
CONFIG_SPIRAM_SPEED_120M=y
|
||||
CONFIG_SPI_FLASH_ROM_IMPL=y
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
Reference in New Issue
Block a user