refactor(spi_flash): move os layer to esp_mspi and chip configs to spi_flash

Also fixes the implicit dependency on esp_partition.
This commit is contained in:
armando
2026-09-09 14:17:00 +08:00
committed by Armando (Dou Yiwen)
parent c565262ded
commit 6e3abd12a1
197 changed files with 1227 additions and 1139 deletions
@@ -4,9 +4,9 @@ components/spi_flash/test_apps/esp_flash:
depends_filepatterns:
- components/bootloader_support/bootloader_flash/**/*
depends_components:
- *common_components
- esp_mm
- esp_psram
- esp_mspi
- spi_flash
- esp_driver_gpio
- esp_driver_spi
@@ -19,14 +19,14 @@ components/spi_flash/test_apps/esp_flash_blockdev:
temporary: false
reason: should be sufficient to test on one Xtensa and one RISC-V target
depends_components:
- *common_components
- esp_mspi
- spi_flash
components/spi_flash/test_apps/esp_flash_freq_limit:
enable:
- if: IDF_TARGET == "esp32c5"
depends_components:
- *common_components
- esp_mspi
- spi_flash
- esp_pm
- esp_driver_gptimer
@@ -34,7 +34,7 @@ components/spi_flash/test_apps/esp_flash_freq_limit:
components/spi_flash/test_apps/esp_flash_stress:
depends_components:
- *common_components
- esp_mspi
- esp_mm
- spi_flash
- esp_hal_mspi
@@ -51,14 +51,14 @@ components/spi_flash/test_apps/flash_encryption:
reason: No runners # IDF-5634
depends_components:
- *common_components
- esp_mspi
- esp_mm
- spi_flash
- esp_hal_mspi
components/spi_flash/test_apps/flash_mmap:
depends_components:
- *common_components
- esp_mspi
- esp_mm
- spi_flash
- esp_hal_mspi
@@ -82,7 +82,7 @@ components/spi_flash/test_apps/flash_suspend:
temporary: true
reason: lack of runners, or we don't trust generic runner must support suspend
depends_components:
- *common_components
- esp_mspi
- spi_flash
- esp_driver_gptimer
- esp_hal_mspi
@@ -94,7 +94,7 @@ components/spi_flash/test_apps/mspi_test:
depends_filepatterns:
- components/bootloader_support/bootloader_flash/**/*
depends_components:
- *common_components
- esp_mspi
- esp_mm
- esp_psram
- spi_flash
@@ -102,8 +102,3 @@ components/spi_flash/test_apps/mspi_test:
- esp_driver_spi
- esptool_py # Some flash related kconfigs are listed here.
- esp_hal_mspi
components/spi_flash/test_apps/no_flash_delay:
disable:
- if: IDF_TARGET not in ["esp32c3"]
reason: Testing on a single target is sufficient
@@ -22,7 +22,7 @@ const esp_partition_t *get_test_flash_partition(void)
{
/* This finds "flash_test" partition defined in custom partitions.csv */
const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
ESP_PARTITION_SUBTYPE_ANY, "flash_test");
ESP_PARTITION_SUBTYPE_ANY, "flash_test");
assert(result != NULL); /* means partition table set wrong */
return result;
}
@@ -101,7 +101,8 @@ err:
return ret;
}
const esp_partition_t * spi_flash_suspend_test_find_last_partition(void) {
const esp_partition_t * spi_flash_suspend_test_find_last_partition(void)
{
const esp_partition_t *last_partition = NULL;
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL);
@@ -30,13 +30,11 @@ void app_main(void)
// | `---..-' || | --' | |` | |\ '-' |.-' `)| | | |
// `------'`-----' `--' `--' `--' `--`--'`----' `--' `--'
printf(",------. ,---. ,------. ,------.,--. ,--. \n");
printf("| .---'' .-' | .--. ' | .---'| | ,--,--. ,---. | ,---. \n");
printf("| `--, `. `-. | '--' | | `--, | |' ,-. |( .-' | .-. | \n");
printf("| `---..-' || | --' | |` | |\\ '-' |.-' `)| | | | \n");
printf("`------'`-----' `--' `--' `--' `--`--'`----' `--' `--' \n");
unity_run_menu();
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -120,7 +120,6 @@ typedef void (*flash_test_func_t)(const esp_partition_t *part);
LOG_ERASE(bus, erase_2, chip); \
} while (0)
#if defined(CONFIG_SPIRAM)
//SPI1 CS1 occupied by PSRAM
#define BYPASS_MULTIPLE_CHIP 1
@@ -182,77 +181,77 @@ static const char TAG[] = "test_esp_flash";
#if CONFIG_IDF_TARGET_ESP32
flashtest_config_t config_list[] = {
FLASHTEST_CONFIG_COMMON,
/* current runner doesn't have a flash on SPI2_HOST */
// {
// .io_mode = TEST_SPI_READ_MODE,
// .freq_mhz = TEST_SPI_SPEED,
// .host_id = SPI2_HOST,
// .cs_id = 0,
// // uses GPIO matrix on esp32s2 regardless if FORCE_GPIO_MATRIX
// .cs_io_num = SPI2_PIN_NUM_CS,
// .input_delay_ns = 20,
// },
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI3_HOST,
.cs_id = 0,
.cs_io_num = SPI3_PIN_NUM_CS,
.input_delay_ns = 0,
},
};
FLASHTEST_CONFIG_COMMON,
/* current runner doesn't have a flash on SPI2_HOST */
// {
// .io_mode = TEST_SPI_READ_MODE,
// .freq_mhz = TEST_SPI_SPEED,
// .host_id = SPI2_HOST,
// .cs_id = 0,
// // uses GPIO matrix on esp32s2 regardless if FORCE_GPIO_MATRIX
// .cs_io_num = SPI2_PIN_NUM_CS,
// .input_delay_ns = 20,
// },
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI3_HOST,
.cs_id = 0,
.cs_io_num = SPI3_PIN_NUM_CS,
.input_delay_ns = 0,
},
};
#elif CONFIG_IDF_TARGET_ESP32S2
flashtest_config_t config_list[] = {
FLASHTEST_CONFIG_COMMON,
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI2_HOST,
.cs_id = 0,
.cs_io_num = SPI2_PIN_NUM_CS,
.input_delay_ns = 0,
},
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI3_HOST,
.cs_id = 0,
// uses GPIO matrix on esp32s2 regardless of FORCE_GPIO_MATRIX
.cs_io_num = SPI2_PIN_NUM_CS,
.input_delay_ns = 0,
},
};
FLASHTEST_CONFIG_COMMON,
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI2_HOST,
.cs_id = 0,
.cs_io_num = SPI2_PIN_NUM_CS,
.input_delay_ns = 0,
},
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI3_HOST,
.cs_id = 0,
// uses GPIO matrix on esp32s2 regardless of FORCE_GPIO_MATRIX
.cs_io_num = SPI2_PIN_NUM_CS,
.input_delay_ns = 0,
},
};
#elif CONFIG_IDF_TARGET_ESP32S3
flashtest_config_t config_list[] = {
/* No SPI1 CS1 flash on esp32S3 test */
{
/* no need to init */
.host_id = -1,
},
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI2_HOST,
.cs_id = 0,
.cs_io_num = SPI2_PIN_NUM_CS,
.input_delay_ns = 0,
},
};
/* No SPI1 CS1 flash on esp32S3 test */
{
/* no need to init */
.host_id = -1,
},
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI2_HOST,
.cs_id = 0,
.cs_io_num = SPI2_PIN_NUM_CS,
.input_delay_ns = 0,
},
};
#else
flashtest_config_t config_list[] = {
/* No SPI1 CS1 flash on esp32c3 test */
{
/* no need to init */
.host_id = -1,
},
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI2_HOST,
.cs_id = 0,
.cs_io_num = SPI2_PIN_NUM_CS,
.input_delay_ns = 0,
},
};
/* No SPI1 CS1 flash on esp32c3 test */
{
/* no need to init */
.host_id = -1,
},
{
.io_mode = TEST_SPI_READ_MODE,
.freq_mhz = TEST_SPI_SPEED,
.host_id = SPI2_HOST,
.cs_id = 0,
.cs_io_num = SPI2_PIN_NUM_CS,
.input_delay_ns = 0,
},
};
#endif
@@ -12,7 +12,9 @@
#include <unity.h>
#include "esp_flash.h"
#include "esp_flash_chips/esp_flash_types.h" // For esp_flash_t structure definition
#include "esp_private/spi_common_internal.h"
#include "esp_private/spi_flash_os.h"
#include "esp_flash_spi_init.h"
#include "esp_private/memspi_host_driver.h"
#include <esp_attr.h>
@@ -31,7 +33,6 @@
#include "esp_rom_sys.h"
#include "esp_timer.h"
#include "test_esp_flash_def.h"
#include "esp_private/spi_flash_os.h"
#include "ccomp_timer.h"
static uint8_t sector_buf[4096];
@@ -229,7 +230,7 @@ static void flash_test_func(flash_test_func_t func, int test_num)
{
esp_log_level_set("gpio", ESP_LOG_NONE);
for (int i = 0; i < test_num; i++) {
ESP_LOGI(TAG, "Testing config %u/%u", i+1, test_num);
ESP_LOGI(TAG, "Testing config %u/%u", i + 1, test_num);
flash_test_core(func, &config_list[i]);
}
ESP_LOGI(TAG, "Completed %u configs", test_num);
@@ -264,7 +265,7 @@ static uint32_t erase_test_region(const esp_partition_t *part, int num_sectors)
bzero(sector_buf, sizeof(sector_buf));
printf("Erase @ 0x%lx...\n", offs);
TEST_ASSERT_EQUAL_HEX32(ESP_OK, esp_flash_erase_region(chip, offs, num_sectors * 4096) );
TEST_ASSERT_EQUAL_HEX32(ESP_OK, esp_flash_erase_region(chip, offs, num_sectors * 4096));
printf("Verify erased...\n");
for (int i = 0; i < num_sectors; i++) {
@@ -291,12 +292,12 @@ void test_simple_read_write(const esp_partition_t* part)
}
printf("Write %p...\n", (void *)offs);
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, sector_buf, offs, sizeof(sector_buf)) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, sector_buf, offs, sizeof(sector_buf)));
bzero(sector_buf, sizeof(sector_buf));
printf("Read back...\n");
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, sector_buf, offs, sizeof(sector_buf)) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, sector_buf, offs, sizeof(sector_buf)));
printf("Buffer starts 0x%02x 0x%02x 0x%02x 0x%02x\n", sector_buf[0], sector_buf[1], sector_buf[2], sector_buf[3]);
@@ -317,13 +318,13 @@ void test_unaligned_read_write(const esp_partition_t* part)
const char *msg = "i am a message";
TEST_ASSERT(strlen(msg) + 1 % 4 != 0);
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, msg, offs + 1, strlen(msg) + 1) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, msg, offs + 1, strlen(msg) + 1));
char buf[strlen(msg) + 1];
memset(buf, 0xEE, sizeof(buf));
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, buf, offs + 1, strlen(msg) + 1) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, buf, offs + 1, strlen(msg) + 1));
TEST_ASSERT_EQUAL_STRING_LEN(msg, buf, strlen(msg));
TEST_ASSERT(memcmp(buf, msg, strlen(msg) + 1) == 0);
}
@@ -340,14 +341,14 @@ void test_single_read_write(const esp_partition_t* part)
srand(seed);
for (unsigned v = 0; v < 512; v++) {
uint32_t data = rand();
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_write(chip, &data, offs + v, 1) );
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_write(chip, &data, offs + v, 1));
}
srand(seed);
for (unsigned v = 0; v < 512; v++) {
uint8_t readback;
uint32_t data = rand();
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_read(chip, &readback, offs + v, 1) );
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_read(chip, &readback, offs + v, 1));
TEST_ASSERT_EQUAL_HEX8(data, readback);
}
}
@@ -355,7 +356,6 @@ void test_single_read_write(const esp_partition_t* part)
TEST_CASE_FLASH("SPI flash single byte reads/writes", test_single_read_write);
TEST_CASE_MULTI_FLASH("SPI flash single byte reads/writes", test_single_read_write);
/* this test is notable because it generates a lot of unaligned reads/writes,
and also reads/writes across both a sector boundary & many page boundaries.
*/
@@ -370,14 +370,14 @@ void test_three_byte_read_write(const esp_partition_t* part)
srand(seed);
for (uint32_t v = 0; v < 86; v++) {
uint32_t data = rand();
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, &data, offs + 3 * v, 3) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, &data, offs + 3 * v, 3));
}
srand(seed);
for (uint32_t v = 0; v < 1; v++) {
uint32_t readback;
uint32_t data = rand();
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, &readback, offs + 3 * v, 3) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, &readback, offs + 3 * v, 3));
TEST_ASSERT_EQUAL_HEX32(data & 0xFFFFFF, readback & 0xFFFFFF);
}
}
@@ -478,7 +478,7 @@ void test_flash_wrap(const esp_partition_t* part)
wrap_buf[i] = rand();
}
printf("Write %p...\n", (void *)offs);
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, wrap_buf, offs + 3, sizeof(wrap_buf)) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, wrap_buf, offs + 3, sizeof(wrap_buf)));
bzero(wrap_buf, sizeof(wrap_buf));
@@ -542,7 +542,7 @@ static bool is_mxic_chip(esp_flash_t* chip)
uint32_t flash_id;
esp_err_t ret = esp_flash_read_chip_id(chip, &flash_id);
TEST_ESP_OK(ret);
return (spi_flash_chip_mxic_probe(chip, flash_id)==ESP_OK);
return (spi_flash_chip_mxic_probe(chip, flash_id) == ESP_OK);
}
IRAM_ATTR NOINLINE_ATTR static void test_toggle_qe(const esp_partition_t* part)
@@ -562,7 +562,7 @@ IRAM_ATTR NOINLINE_ATTR static void test_toggle_qe(const esp_partition_t* part)
for (int i = 0; i < 4; i ++) {
esp_rom_printf(DRAM_STR("write qe: %" PRIu32 "->%" PRIu32 "\n"), qe, !qe);
qe = !qe;
chip->read_mode = qe? SPI_FLASH_QOUT: SPI_FLASH_SLOWRD;
chip->read_mode = qe ? SPI_FLASH_QOUT : SPI_FLASH_SLOWRD;
ret = esp_flash_set_io_mode(chip, qe);
if (allow_failure && !qe && ret == ESP_ERR_FLASH_NO_RESPONSE) {
//allows clear qe failure for Winbond chips
@@ -609,7 +609,7 @@ void test_permutations_part(const flashtest_config_t* config, esp_partition_t* p
{
int clock_index = 0;
if (config->host_id != -1) {
while (clock_index < sizeof(flash_frequency_table)/sizeof(uint8_t)) {
while (clock_index < sizeof(flash_frequency_table) / sizeof(uint8_t)) {
uint8_t speed = flash_frequency_table[clock_index];
//test io_mode in the inner loop to test QE set/clear function, since
//the io mode will switch frequently.
@@ -686,16 +686,20 @@ void test_permutations_chip(const flashtest_config_t* config)
}
for (int i = 0; i < 2; i++) {
if (part[i].size == 0) continue;
if (part[i].size == 0) {
continue;
}
write_large_buffer(&part[i], source_buf, length);
}
teardown_test_chip(chip);
for (int i = 0; i < 2; i++) {
if (part[i].size == 0) continue;
if (part[i].size == 0) {
continue;
}
part[i].flash_chip = (esp_flash_t*)-1;
part[i].flash_chip = (esp_flash_t*) -1;
ESP_LOGI(TAG, "Testing address 0x%08lX...", part[i].address);
test_permutations_part(config, &part[i], source_buf, length);
}
@@ -717,7 +721,6 @@ TEST_CASE("SPI flash test reading with all speed/mode permutations, 3 chips", "[
}
#endif
static void test_write_large_const_buffer(const esp_partition_t* part)
{
test_write_large_buffer(part, large_const_buffer, sizeof(large_const_buffer));
@@ -744,10 +747,10 @@ static void write_large_buffer(const esp_partition_t *part, const uint8_t *sourc
esp_flash_t* chip = part->flash_chip;
printf("Writing chip %p %p, %u bytes from source %p\n", chip, (void*)part->address, length, source);
ESP_ERROR_CHECK( esp_flash_erase_region(chip, part->address, (length + part->erase_size) & ~(part->erase_size - 1)) );
ESP_ERROR_CHECK(esp_flash_erase_region(chip, part->address, (length + part->erase_size) & ~(part->erase_size - 1)));
// note writing to unaligned address
ESP_ERROR_CHECK( esp_flash_write(chip, source, part->address + 1, length) );
ESP_ERROR_CHECK(esp_flash_write(chip, source, part->address + 1, length));
}
static void read_and_check(const esp_partition_t *part, const uint8_t *source, size_t length)
@@ -756,18 +759,18 @@ static void read_and_check(const esp_partition_t *part, const uint8_t *source, s
printf("Checking chip %p 0x%08lX, %u bytes\n", chip, part->address, length);
uint8_t *buf = malloc(length);
TEST_ASSERT_NOT_NULL(buf);
ESP_ERROR_CHECK( esp_flash_read(chip, buf, part->address + 1, length) );
ESP_ERROR_CHECK(esp_flash_read(chip, buf, part->address + 1, length));
TEST_ASSERT_EQUAL_HEX8_ARRAY(source, buf, length);
free(buf);
// check nothing was written at beginning or end
uint8_t ends[8];
ESP_ERROR_CHECK( esp_flash_read(chip, ends, part->address, sizeof(ends)) );
ESP_ERROR_CHECK(esp_flash_read(chip, ends, part->address, sizeof(ends)));
TEST_ASSERT_EQUAL_HEX8(0xFF, ends[0]);
TEST_ASSERT_EQUAL_HEX8(source[0], ends[1]);
ESP_ERROR_CHECK( esp_flash_read(chip, ends, part->address + length, sizeof(ends)) );
ESP_ERROR_CHECK(esp_flash_read(chip, ends, part->address + length, sizeof(ends)));
TEST_ASSERT_EQUAL_HEX8(source[length - 1], ends[0]);
TEST_ASSERT_EQUAL_HEX8(0xFF, ends[1]);
@@ -793,20 +796,20 @@ static void test_write_over_boundary(const esp_partition_t* part)
const uint32_t SECTOR_SIZE = 4096;
uint8_t buf[0];
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size+SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, SECTOR_SIZE, flash_size));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2, flash_size/2 + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2 + SECTOR_SIZE, flash_size/2));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size / 2, flash_size / 2 + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size / 2 + SECTOR_SIZE, flash_size / 2));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, UINT32_MAX - SECTOR_SIZE + 1));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, UINT32_MAX - SECTOR_SIZE + 1, flash_size - SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, 0, flash_size+SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, 0, flash_size + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, SECTOR_SIZE, flash_size));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size/2, flash_size/2 + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size/2 + SECTOR_SIZE, flash_size/2));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size / 2, flash_size / 2 + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size / 2 + SECTOR_SIZE, flash_size / 2));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE));
@@ -836,7 +839,7 @@ static uint32_t time_measure_end(time_meas_ctx_t* ctx)
uint32_t c_time_us = ccomp_timer_stop();
uint32_t time_us = esp_timer_get_time() - ctx->us_start;
ESP_LOGI(TAG, "%s: compensated: %.2lf kB/s, typical: %.2lf kB/s", ctx->name, ctx->len / (c_time_us / 1000.), ctx->len / (time_us/1000.));
ESP_LOGI(TAG, "%s: compensated: %.2lf kB/s, typical: %.2lf kB/s", ctx->name, ctx->len / (c_time_us / 1000.), ctx->len / (time_us / 1000.));
return ctx->len * 1000 / (c_time_us / 1000);
}
@@ -902,8 +905,7 @@ static uint32_t measure_read(const char* name, const esp_partition_t* part, uint
static const char* get_chip_vendor(uint32_t id)
{
switch (id)
{
switch (id) {
case 0x20:
return "XMC";
break;
@@ -967,7 +969,7 @@ static void test_flash_read_write_performance(const esp_partition_t *part)
LOG_PERFORMANCE(EXT_, chip_name);
} else if (cs_id == 0) {
// Main flash
LOG_PERFORMANCE(,chip_name);
LOG_PERFORMANCE(, chip_name);
} else {
// Other cs pins on SPI1
LOG_PERFORMANCE(SPI1_, chip_name);
@@ -978,7 +980,10 @@ static void test_flash_read_write_performance(const esp_partition_t *part)
#if !BYPASS_MULTIPLE_CHIP
//To make performance data stable, needs to run on special runner
TEST_CASE("Test esp_flash read/write performance", "[esp_flash][test_env=UT_T1_ESP_FLASH]") {flash_test_func(test_flash_read_write_performance, 1);}
TEST_CASE("Test esp_flash read/write performance", "[esp_flash][test_env=UT_T1_ESP_FLASH]")
{
flash_test_func(test_flash_read_write_performance, 1);
}
#endif
TEST_CASE_MULTI_FLASH("Test esp_flash read/write performance", test_flash_read_write_performance);
@@ -992,12 +997,12 @@ TEST_CASE_MULTI_FLASH("Test esp_flash read/write performance", test_flash_read_w
static void s_test_compare_flash_contents_small_reads(esp_flash_t *chip, const uint8_t *buffer, size_t offs, size_t len)
{
const size_t INTERNAL_BUF_SZ = 1024; // Should fit in internal RAM
uint8_t *ibuf = heap_caps_malloc(INTERNAL_BUF_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
uint8_t *ibuf = heap_caps_malloc(INTERNAL_BUF_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
TEST_ASSERT_NOT_NULL(ibuf);
for (int i = 0; i < len; i += INTERNAL_BUF_SZ) {
size_t to_read = MIN(INTERNAL_BUF_SZ, len - i);
ESP_ERROR_CHECK( esp_flash_read(chip, ibuf, offs + i, to_read) );
ESP_ERROR_CHECK(esp_flash_read(chip, ibuf, offs + i, to_read));
TEST_ASSERT_EQUAL_HEX8_ARRAY(buffer + i, ibuf, to_read);
}
@@ -1010,10 +1015,10 @@ static void test_flash_read_large_psram_buffer(const esp_partition_t *part)
const size_t BUF_SZ = 256 * 1024; // Too large for internal RAM
const size_t TEST_OFFS = 0x1000; // Can be any offset, really
uint8_t *buf = heap_caps_malloc(BUF_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_SPIRAM);
uint8_t *buf = heap_caps_malloc(BUF_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
TEST_ASSERT_NOT_NULL(buf);
ESP_ERROR_CHECK( esp_flash_read(chip, buf, TEST_OFFS, BUF_SZ) );
ESP_ERROR_CHECK(esp_flash_read(chip, buf, TEST_OFFS, BUF_SZ));
// Read back the same into smaller internal memory buffer and check it all matches
s_test_compare_flash_contents_small_reads(chip, buf, TEST_OFFS, BUF_SZ);
@@ -1023,7 +1028,6 @@ static void test_flash_read_large_psram_buffer(const esp_partition_t *part)
TEST_CASE_FLASH("esp_flash_read large PSRAM buffer", test_flash_read_large_psram_buffer);
/* similar to above test, but perform it under memory pressure */
static void test_flash_read_large_psram_buffer_low_internal_mem(const esp_partition_t *part)
{
@@ -1033,14 +1037,14 @@ static void test_flash_read_large_psram_buffer_low_internal_mem(const esp_partit
const size_t TEST_OFFS = 0x8000;
/* Exhaust the available free internal memory */
test_utils_exhaust_memory_rec erec = test_utils_exhaust_memory(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT, REMAINING_INTERNAL);
test_utils_exhaust_memory_rec erec = test_utils_exhaust_memory(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT, REMAINING_INTERNAL);
uint8_t *buf = heap_caps_malloc(BUF_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_SPIRAM);
uint8_t *buf = heap_caps_malloc(BUF_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
TEST_ASSERT_NOT_NULL(buf);
/* Calling esp_flash_read() here will need to allocate a small internal buffer,
so check it works. */
ESP_ERROR_CHECK( esp_flash_read(chip, buf, TEST_OFFS, BUF_SZ) );
ESP_ERROR_CHECK(esp_flash_read(chip, buf, TEST_OFFS, BUF_SZ));
test_utils_free_exhausted_memory(erec);
@@ -1053,7 +1057,6 @@ static void test_flash_read_large_psram_buffer_low_internal_mem(const esp_partit
TEST_CASE_FLASH("esp_flash_read large PSRAM buffer low memory", test_flash_read_large_psram_buffer_low_internal_mem);
#endif
#if CONFIG_SPI_FLASH_ENABLE_COUNTERS
#define TEST_CNT_RW_TIMES 4
#define TEST_CNT_RW_LEN 64
@@ -1066,7 +1069,7 @@ void test_flash_counter(const esp_partition_t* part)
static uint8_t write_buf[TEST_CNT_RW_LEN * TEST_CNT_RW_TIMES];
static uint8_t read_buf[TEST_CNT_RW_LEN * TEST_CNT_RW_TIMES];
for(int i = 0;i < TEST_CNT_RW_LEN * TEST_CNT_RW_TIMES; i ++){
for (int i = 0; i < TEST_CNT_RW_LEN * TEST_CNT_RW_TIMES; i ++) {
write_buf[i] = i;
}
@@ -1086,15 +1089,15 @@ void test_flash_counter(const esp_partition_t* part)
TEST_ASSERT_EQUAL_UINT32(TEST_CNT_ERASE_LEN, flash_counter.erase.bytes);
int count;
for(count = 0; count < TEST_CNT_RW_TIMES; count ++) {
for (count = 0; count < TEST_CNT_RW_TIMES; count ++) {
// check counter on write option
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, write_buf + TEST_CNT_RW_LEN * count, offs + TEST_CNT_RW_LEN * count, TEST_CNT_RW_LEN) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, write_buf + TEST_CNT_RW_LEN * count, offs + TEST_CNT_RW_LEN * count, TEST_CNT_RW_LEN));
flash_counter = *esp_flash_get_counters();
TEST_ASSERT_EQUAL_UINT32((count + 1), flash_counter.write.count);
TEST_ASSERT_EQUAL_UINT32((count + 1) * TEST_CNT_RW_LEN, flash_counter.write.bytes);
// check counter on read option
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, read_buf + TEST_CNT_RW_LEN * count, offs + TEST_CNT_RW_LEN * count, TEST_CNT_RW_LEN) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, read_buf + TEST_CNT_RW_LEN * count, offs + TEST_CNT_RW_LEN * count, TEST_CNT_RW_LEN));
flash_counter = *esp_flash_get_counters();
TEST_ASSERT_EQUAL_UINT32((count + 1), flash_counter.read.count);
TEST_ASSERT_EQUAL_UINT32((count + 1) * TEST_CNT_RW_LEN, flash_counter.read.bytes);
@@ -1114,8 +1117,8 @@ void test_flash_counter(const esp_partition_t* part)
TEST_ASSERT_EACH_EQUAL_HEX8(0, &flash_counter, sizeof(esp_flash_counters_t));
#if SOC_FLASH_ENC_SUPPORTED
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write_encrypted(chip, offs, write_buf, TEST_CNT_RW_LEN) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read_encrypted(chip, offs, read_buf, TEST_CNT_RW_LEN) );
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write_encrypted(chip, offs, write_buf, TEST_CNT_RW_LEN));
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read_encrypted(chip, offs, read_buf, TEST_CNT_RW_LEN));
printf("\ntest for encrypted write/read\n");
esp_flash_dump_counters(stdout);
@@ -1137,7 +1140,7 @@ TEST_CASE_FLASH("SPI flash counter test", test_flash_counter);
#if CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS
TEST_CASE("test writes to dangerous regions like bootloader", "[esp_flash]")
{
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4*4096));
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4 * 4096));
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_PARTITION_TABLE_OFFSET, 4096));
char buffer[32] = {0xa5};
// Encrypted writes to bootloader region not allowed
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -10,7 +10,6 @@
#include <freertos/semphr.h>
#include "unity.h"
#include "spi_flash_mmap.h"
#include "esp_attr.h"
#include "esp_intr_alloc.h"
#include "ccomp_timer.h"
@@ -20,6 +19,8 @@
#include "esp_timer.h"
#include "esp_partition.h"
#include "bootloader_flash.h" //for bootloader_flash_xmc_startup
#include "esp_flash.h"
#include "spi_flash_mmap.h"
#include "test_utils.h"
#include "sdkconfig.h"
@@ -96,11 +97,11 @@ TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_fla
SemaphoreHandle_t done = xSemaphoreCreateCounting(4, 0);
struct flash_test_ctx ctx[] = {
{ .offset = 0x10 + 6, .done = done },
{ .offset = 0x10 + 7, .done = done },
{ .offset = 0x10 + 8, .done = done },
{ .offset = 0x10 + 6, .done = done },
{ .offset = 0x10 + 7, .done = done },
{ .offset = 0x10 + 8, .done = done },
#ifndef CONFIG_FREERTOS_UNICORE
{ .offset = 0x10 + 9, .done = done }
{ .offset = 0x10 + 9, .done = done }
#endif
};
@@ -111,7 +112,7 @@ TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_fla
xTaskCreatePinnedToCore(flash_test_task, "t3", 2048, &ctx[3], 3, NULL, 1);
#endif
const size_t task_count = sizeof(ctx)/sizeof(ctx[0]);
const size_t task_count = sizeof(ctx) / sizeof(ctx[0]);
for (int i = 0; i < task_count; ++i) {
xSemaphoreTake(done, portMAX_DELAY);
}
@@ -903,7 +903,6 @@ static void cleanup_interrupt_timer(void)
}
}
/**
* Helper function: Test interrupt during encrypt with PM configuration
* Common test logic for both PM enabled and disabled scenarios
@@ -1247,5 +1246,4 @@ TEST_CASE("Frequency limit: APB lock released in ISR", "[esp_flash_freq_limit]")
}
#endif // CONFIG_PM_ENABLE
#endif // CONFIG_IDF_TARGET_ESP32C5
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -127,7 +127,7 @@ TEST_CASE("Flash UniCore: Test ESP Flash API Concurrency [Stress]", "[esp_flash]
xTaskCreatePinnedToCore(&s_test_flash_ops_task, flash_task_name, 4096, (void *)(&ctx), 5, NULL, 0);
}
while(1);
while (1);
}
#if !CONFIG_FREERTOS_UNICORE
@@ -167,7 +167,6 @@ TEST_CASE("Flash DualCore: Test ESP Flash API Concurrency", "[esp_flash]")
vSemaphoreDelete(s_test_concurrency_smphr);
}
/**
* esp_flash APIs concurrency pressure test
* This test is for manually test
@@ -195,6 +194,6 @@ TEST_CASE("Flash DualCore: Test ESP Flash API Concurrency [Stress]", "[esp_flash
xTaskCreatePinnedToCore(&s_test_flash_ops_task, flash_task_name, 4096, (void *)(&ctx), 5, NULL, 1);
}
while(1);
while (1);
}
#endif //#if !CONFIG_FREERTOS_UNICORE
@@ -2,5 +2,6 @@ set(srcs "test_app_main.c"
"test_flash_encryption.c")
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES unity spi_flash bootloader_support esp_partition test_utils test_flash_utils
PRIV_REQUIRES unity spi_flash bootloader_support esp_partition test_utils
test_flash_utils
WHOLE_ARCHIVE)
@@ -25,7 +25,7 @@ static void check_leak(size_t before_free, size_t after_free, const char *type)
void setUp(void)
{
// Calling esp_partition_find_first ensures that the paritions have been loaded
// Calling esp_partition_find_first ensures that the partitions have been loaded
// and subsequent calls to esp_partition_find_first from the tests would not
// load partitions which otherwise gets considered as a memory leak.
esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -50,7 +50,7 @@ static void setup_tests(void)
static void verify_erased_flash(size_t offset, size_t length)
{
uint8_t *readback = (uint8_t *)heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
printf("verify erased 0x%" PRIx32 " - 0x%" PRIx32 "\n", (uint32_t) offset, (uint32_t) (offset + length));
printf("verify erased 0x%" PRIx32 " - 0x%" PRIx32 "\n", (uint32_t) offset, (uint32_t)(offset + length));
TEST_ASSERT_EQUAL_HEX(ESP_OK,
esp_flash_read(NULL, readback, offset, length));
for (int i = 0; i < length; i++) {
@@ -64,19 +64,19 @@ TEST_CASE("test 16 byte encrypted writes", "[flash_encryption]")
setup_tests();
TEST_ASSERT_EQUAL_HEX(ESP_OK,
esp_flash_erase_region(NULL, start, SPI_FLASH_SEC_SIZE));
esp_flash_erase_region(NULL, start, SPI_FLASH_SEC_SIZE));
uint8_t fortyeight_bytes[0x30]; // 0, 1, 2, 3, 4... 47
for(int i = 0; i < sizeof(fortyeight_bytes); i++) {
for (int i = 0; i < sizeof(fortyeight_bytes); i++) {
fortyeight_bytes[i] = i;
}
/* Verify unaligned start or length fails */
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG,
esp_flash_write_encrypted(NULL, start + 1, fortyeight_bytes, 32));
esp_flash_write_encrypted(NULL, start + 1, fortyeight_bytes, 32));
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_SIZE,
esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15));
esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15));
/* ensure nothing happened to the flash yet */
verify_erased_flash(start, 0x20);
@@ -87,8 +87,8 @@ TEST_CASE("test 16 byte encrypted writes", "[flash_encryption]")
/* Slip in an unaligned esp_flash_read_encrypted() test */
uint8_t buf[0x10];
esp_flash_read_encrypted(NULL, start+0x10, buf, 0x10);
TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes+0x10, buf, 16);
esp_flash_read_encrypted(NULL, start + 0x10, buf, 0x10);
TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes + 0x10, buf, 16);
/* Write 16 bytes unaligned */
test_encrypted_write(start + 0x30, fortyeight_bytes, 0x10);
@@ -124,7 +124,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]")
{
const int MAX_LEN = 192;
//buffer to hold the read data
WORD_ALIGNED_ATTR uint8_t buffer_to_write[MAX_LEN+4];
WORD_ALIGNED_ATTR uint8_t buffer_to_write[MAX_LEN + 4];
//test with unaligned buffer
uint8_t* data_buf = &buffer_to_write[3];
@@ -145,7 +145,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]")
do {
//the encrypted write only works at 16-byte boundary
int skip = (rand() % 4) * 16;
int len = ((rand() % (MAX_LEN/16)) + 1) * 16;
int len = ((rand() % (MAX_LEN / 16)) + 1) * 16;
for (int i = 0; i < MAX_LEN; i++) {
data_buf[i] = rand();
@@ -159,7 +159,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]")
len = SPI_FLASH_SEC_SIZE - offset;
}
printf("write %d bytes to 0x%08" PRIx32 "...\n", len, (uint32_t) (start + offset));
printf("write %d bytes to 0x%08" PRIx32 "...\n", len, (uint32_t)(start + offset));
err = esp_flash_write_encrypted(NULL, start + offset, data_buf, len);
TEST_ESP_OK(err);
@@ -169,7 +169,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]")
offset = 0;
do {
int len = ((rand() % (MAX_LEN/16)) + 1) * 16;
int len = ((rand() % (MAX_LEN / 16)) + 1) * 16;
if (offset + len > SPI_FLASH_SEC_SIZE) {
len = SPI_FLASH_SEC_SIZE - offset;
}
@@ -177,7 +177,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]")
err = esp_flash_read_encrypted(NULL, start + offset, data_buf, len);
TEST_ESP_OK(err);
printf("compare %d bytes at 0x%08" PRIx32 "...\n", len, (uint32_t) (start + offset));
printf("compare %d bytes at 0x%08" PRIx32 "...\n", len, (uint32_t)(start + offset));
TEST_ASSERT_EQUAL_HEX8_ARRAY(cmp_buf + offset, data_buf, len);
offset += len;
@@ -208,19 +208,19 @@ TEST_CASE("test 16 byte encrypted writes (esp_flash)", "[flash_encryption]")
setup_tests();
TEST_ASSERT_EQUAL_HEX(ESP_OK,
esp_flash_erase_region(NULL, start, SPI_FLASH_SEC_SIZE));
esp_flash_erase_region(NULL, start, SPI_FLASH_SEC_SIZE));
uint8_t fortyeight_bytes[0x30]; // 0, 1, 2, 3, 4... 47
for(int i = 0; i < sizeof(fortyeight_bytes); i++) {
for (int i = 0; i < sizeof(fortyeight_bytes); i++) {
fortyeight_bytes[i] = i;
}
/* Verify unaligned start or length fails */
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG,
esp_flash_write_encrypted(NULL, start+1, fortyeight_bytes, 32));
esp_flash_write_encrypted(NULL, start + 1, fortyeight_bytes, 32));
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_SIZE,
esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15));
esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15));
/* ensure nothing happened to the flash yet */
verify_erased_flash(start, 0x20);
@@ -231,8 +231,8 @@ TEST_CASE("test 16 byte encrypted writes (esp_flash)", "[flash_encryption]")
/* Slip in an unaligned esp_flash_read_encrypted() test */
uint8_t buf[0x10];
esp_flash_read_encrypted(NULL, start+0x10, buf, 0x10);
TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes+0x10, buf, 16);
esp_flash_read_encrypted(NULL, start + 0x10, buf, 0x10);
TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes + 0x10, buf, 16);
/* Write 16 bytes unaligned */
test_encrypted_write_new_impl(start + 0x30, fortyeight_bytes, 0x10);
@@ -392,7 +392,7 @@ TEST_CASE("test read & write encrypted data with large buffer(n*64+32+16)", "[fl
TEST_ESP_OK(ccomp_timer_start());
TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, large_const_buffer, sizeof(large_const_buffer)));
int64_t write_time = ccomp_timer_stop();
IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time/sizeof(large_const_buffer))*1024);
IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time / sizeof(large_const_buffer)) * 1024);
uint8_t *buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer), MALLOC_CAP_8BIT);
@@ -412,7 +412,7 @@ TEST_CASE("test read & write encrypted data with large buffer(n*64+32+16)", "[fl
TEST_ESP_OK(ccomp_timer_start());
TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, large_const_buffer, sizeof(large_const_buffer)));
write_time = ccomp_timer_stop();
IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time/sizeof(large_const_buffer))*1024);
IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time / sizeof(large_const_buffer)) * 1024);
buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer), MALLOC_CAP_8BIT);
@@ -446,7 +446,7 @@ TEST_CASE("test read & write encrypted data with large buffer in ram", "[flash_e
TEST_ESP_OK(ccomp_timer_start());
TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, large_const_buffer_dram, sizeof(large_const_buffer_dram)));
int64_t write_time = ccomp_timer_stop();
IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time/sizeof(large_const_buffer_dram))*1024);
IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time / sizeof(large_const_buffer_dram)) * 1024);
uint8_t *buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer_dram), MALLOC_CAP_32BIT | MALLOC_CAP_8BIT);
TEST_ESP_OK(esp_flash_read_encrypted(NULL, start, buf, sizeof(large_const_buffer_dram)));
@@ -457,7 +457,7 @@ TEST_CASE("test read & write encrypted data with large buffer in ram", "[flash_e
#if CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS
TEST_CASE("test encrypted writes to dangerous regions like bootloader", "[flash_encryption]")
{
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4*4096));
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4 * 4096));
TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_PARTITION_TABLE_OFFSET, 4096));
char buffer[32] = {0xa5};
// Encrypted writes to bootloader region not allowed
@@ -475,20 +475,20 @@ TEST_CASE("Test flash encrypted write over boundary", "[flash_encryption]")
const uint32_t SECTOR_SIZE = 4096;
uint8_t buf[0];
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size+SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, SECTOR_SIZE, flash_size));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2, flash_size/2 + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2 + SECTOR_SIZE, flash_size/2));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size / 2, flash_size / 2 + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size / 2 + SECTOR_SIZE, flash_size / 2));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, UINT32_MAX - SECTOR_SIZE + 1));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, UINT32_MAX - SECTOR_SIZE + 1, flash_size - SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, 0, buf, flash_size+SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, 0, buf, flash_size + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, SECTOR_SIZE, buf, flash_size));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size/2, buf, flash_size/2 + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size/2 + SECTOR_SIZE, buf, flash_size/2));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size / 2, buf, flash_size / 2 + SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size / 2 + SECTOR_SIZE, buf, flash_size / 2));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size - SECTOR_SIZE, buf, 2 * SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, 2 * SECTOR_SIZE, buf, flash_size - SECTOR_SIZE));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size - SECTOR_SIZE, buf, flash_size - SECTOR_SIZE));
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -14,7 +14,6 @@
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
@@ -41,7 +40,6 @@ void app_main(void)
*/
printf("______ _ ___ _____ _ _ ___ ______ ___ ___ ______\n");
printf("| ___| | / _ \\ / ___| | | | | \\/ || \\/ | / _ \\ | ___ \\\n");
printf("| |_ | | / /_\\ \\\\ `--.| |_| | | . . || . . |/ /_\\ \\| |_/ /\n");
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
from pytest_embedded import Dut
@@ -14,7 +14,6 @@
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
@@ -47,7 +47,6 @@ DRAM_ATTR static uint32_t s_isr_interval_t2;
DRAM_ATTR static uint32_t s_isr_interval_time;
DRAM_ATTR static uint32_t times = 0;
static NOINLINE_ATTR void func_in_flash(void)
{
/**
@@ -66,7 +65,7 @@ static NOINLINE_ATTR void func_in_flash(void)
static bool IRAM_ATTR gptimer_alarm_suspend_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
{
s_isr_t1 = esp_cpu_get_cycle_count();
if (s_isr_interval_t1 != 0 ) {
if (s_isr_interval_t1 != 0) {
s_isr_interval_t2 = esp_cpu_get_cycle_count();
s_isr_interval_time += (s_isr_interval_t2 - s_isr_interval_t1);
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -22,8 +22,8 @@
static const uint8_t large_const_buffer[16400] = {
203, // first byte
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
[50 ... 99] = 2,
[1600 ... 2000] = 3,
[8000 ... 9000] = 77,
@@ -37,7 +37,7 @@ const esp_partition_t *get_test_data_partition(void)
{
/* This finds "flash_test" partition defined in partition_table_unit_test_app.csv */
const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
ESP_PARTITION_SUBTYPE_ANY, "flash_test");
ESP_PARTITION_SUBTYPE_ANY, "flash_test");
TEST_ASSERT_NOT_NULL(result); /* means partition table set wrong */
return result;
}
@@ -68,12 +68,12 @@ static void test_write_large_buffer(const uint8_t *source, size_t length)
uint8_t *buf = malloc(length);
TEST_ASSERT_NOT_NULL(buf);
TEST_ESP_OK( esp_flash_erase_region(NULL, part->address, (length + part->erase_size) & ~(part->erase_size-1)) );
TEST_ESP_OK(esp_flash_erase_region(NULL, part->address, (length + part->erase_size) & ~(part->erase_size - 1)));
// note writing to unaligned address
TEST_ESP_OK( esp_flash_write(NULL, source, part->address + 1, length) );
TEST_ESP_OK(esp_flash_write(NULL, source, part->address + 1, length));
TEST_ESP_OK( esp_flash_read(NULL, buf, part->address + 1, length) );
TEST_ESP_OK(esp_flash_read(NULL, buf, part->address + 1, length));
TEST_ASSERT_EQUAL_HEX8_ARRAY(source, buf, length);
@@ -82,12 +82,12 @@ static void test_write_large_buffer(const uint8_t *source, size_t length)
// check nothing was written at beginning or end
uint8_t ends[8];
TEST_ESP_OK( esp_flash_read(NULL, ends, part->address, sizeof(ends)) );
TEST_ESP_OK(esp_flash_read(NULL, ends, part->address, sizeof(ends)));
TEST_ASSERT_EQUAL_HEX8(0xFF, ends[0]);
TEST_ASSERT_EQUAL_HEX8(source[0] , ends[1]);
TEST_ASSERT_EQUAL_HEX8(source[0], ends[1]);
TEST_ESP_OK( esp_flash_read(NULL, ends, part->address + length, sizeof(ends)) );
TEST_ASSERT_EQUAL_HEX8(source[length-1], ends[0]);
TEST_ESP_OK(esp_flash_read(NULL, ends, part->address + length, sizeof(ends)));
TEST_ASSERT_EQUAL_HEX8(source[length - 1], ends[0]);
TEST_ASSERT_EQUAL_HEX8(0xFF, ends[1]);
TEST_ASSERT_EQUAL_HEX8(0xFF, ends[2]);
TEST_ASSERT_EQUAL_HEX8(0xFF, ends[3]);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -50,7 +50,7 @@ static void setup_tests(void)
static void fill(char *dest, int32_t start, int32_t len)
{
for (int32_t i = 0; i < len; i++) {
*(dest + i) = (char) (start + i);
*(dest + i) = (char)(start + i);
}
}
@@ -330,8 +330,7 @@ TEST_CASE("esp_flash_write can write from external RAM buffer", "[spi_flash]")
TEST_ASSERT_NOT_NULL(buf_ext);
srand(0);
for (size_t i = 0; i < SPI_FLASH_SEC_SIZE / sizeof(uint32_t); i++)
{
for (size_t i = 0; i < SPI_FLASH_SEC_SIZE / sizeof(uint32_t); i++) {
uint32_t val = rand();
buf_ext[i] = val;
}
@@ -1,10 +0,0 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.22)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(test_build)
@@ -1,6 +0,0 @@
| Supported Targets | ESP32-C3 |
| ----------------- | -------- |
This project tests building with the no_flash_delay configuration.
This project uses MINIMAL_BUILD=y to reduce build time and dependencies.
@@ -1,2 +0,0 @@
idf_component_register(SRCS "test_main.c"
INCLUDE_DIRS ".")
@@ -1,8 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
void app_main(void)
{
}
@@ -1 +0,0 @@
CONFIG_SPI_FLASH_YIELD_DURING_ERASE=n
@@ -1,10 +0,0 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.22)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(test_build)
@@ -1,6 +0,0 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
This project tests building with the spi_flash_opts configuration.
This project uses MINIMAL_BUILD=y to reduce build time and dependencies.
@@ -1,2 +0,0 @@
idf_component_register(SRCS "test_main.c"
INCLUDE_DIRS ".")
@@ -1,8 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
void app_main(void)
{
}
@@ -1 +0,0 @@
CONFIG_SPI_FLASH_SIZE_OVERRIDE=y