Merge branch 'refactor/move_flash_mmap_tests_to_test_apps' into 'master'

flash_mmap: move flash mmap tests to test apps

Closes IDF-6134 and IDF-5138

See merge request espressif/esp-idf!20789
This commit is contained in:
Armando (Dou Yiwen)
2022-11-01 20:00:33 +08:00
10 changed files with 168 additions and 64 deletions

View File

@@ -5,7 +5,7 @@
*/ */
#include "unity.h" #include "unity.h"
#include "unity_test_runner.h" #include "unity_test_utils.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
// Some resources are lazy allocated in flash encryption, the threadhold is left for that case // Some resources are lazy allocated in flash encryption, the threadhold is left for that case
@@ -14,12 +14,6 @@
static size_t before_free_8bit; static size_t before_free_8bit;
static size_t before_free_32bit; static size_t before_free_32bit;
static void check_leak(size_t before_free, size_t after_free, const char *type)
{
ssize_t delta = after_free - before_free;
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
}
void setUp(void) void setUp(void)
{ {
@@ -31,8 +25,8 @@ void tearDown(void)
{ {
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
check_leak(before_free_8bit, after_free_8bit, "8BIT"); unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
check_leak(before_free_32bit, after_free_32bit, "32BIT"); unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
} }
void app_main(void) void app_main(void)

View File

@@ -0,0 +1,7 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_mmap)

View File

@@ -0,0 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |

View File

@@ -0,0 +1,7 @@
set(srcs "test_app_main.c"
"test_mmap.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}
WHOLE_ARCHIVE)

View File

@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
// Some resources are lazy allocated, the threadhold is left for that case
#define TEST_MEMORY_LEAK_THRESHOLD (-600)
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);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main(void)
{
/*
______ _ ___ _____ _ _ ___ ______ ___ ___ ______
| ___| | / _ \ / ___| | | | | \/ || \/ | / _ \ | ___ \
| |_ | | / /_\ \\ `--.| |_| | | . . || . . |/ /_\ \| |_/ /
| _| | | | _ | `--. \ _ | | |\/| || |\/| || _ || __/
| | | |____| | | |/\__/ / | | | | | | || | | || | | || |
\_| \_____/\_| |_/\____/\_| |_/ \_| |_/\_| |_/\_| |_/\_|
*/
printf("______ _ ___ _____ _ _ ___ ______ ___ ___ ______\n");
printf("| ___| | / _ \\ / ___| | | | | \\/ || \\/ | / _ \\ | ___ \\\n");
printf("| |_ | | / /_\\ \\\\ `--.| |_| | | . . || . . |/ /_\\ \\| |_/ /\n");
printf("| _| | | | _ | `--. \\ _ | | |\\/| || |\\/| || _ || __/\n");
printf("| | | |____| | | |/\\__/ / | | | | | | || | | || | | || |\n");
printf("\\_| \\_____/\\_| |_/\\____/\\_| |_/ \\_| |_/\\_| |_/\\_| |_/\\_|\n");
unity_run_menu();
}

View File

@@ -1,6 +1,12 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <inttypes.h>
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
#include <freertos/semphr.h> #include <freertos/semphr.h>
@@ -14,8 +20,6 @@
#include "test_utils.h" #include "test_utils.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5138
static uint32_t buffer[1024]; static uint32_t buffer[1024];
/* read-only region used for mmap tests, intialised in setup_mmap_tests() */ /* read-only region used for mmap tests, intialised in setup_mmap_tests() */
@@ -23,7 +27,6 @@ static uint32_t start;
static uint32_t end; static uint32_t end;
static spi_flash_mmap_handle_t handle1, handle2, handle3; static spi_flash_mmap_handle_t handle1, handle2, handle3;
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
static esp_err_t spi_flash_read_maybe_encrypted(size_t src_addr, void *des_addr, size_t size) static esp_err_t spi_flash_read_maybe_encrypted(size_t src_addr, void *des_addr, size_t size)
{ {
@@ -34,8 +37,6 @@ static esp_err_t spi_flash_read_maybe_encrypted(size_t src_addr, void *des_addr,
} }
} }
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5138
static esp_err_t spi_flash_write_maybe_encrypted(size_t des_addr, const void *src_addr, size_t size) static esp_err_t spi_flash_write_maybe_encrypted(size_t des_addr, const void *src_addr, size_t size)
{ {
if (!esp_flash_encryption_enabled()) { if (!esp_flash_encryption_enabled()) {
@@ -51,7 +52,7 @@ static void setup_mmap_tests(void)
const esp_partition_t *part = get_test_data_partition(); const esp_partition_t *part = get_test_data_partition();
start = part->address; start = part->address;
end = part->address + part->size; end = part->address + part->size;
printf("Test data partition @ 0x%x - 0x%x\n", start, end); printf("Test data partition @ 0x%"PRIx32" - 0x%"PRIx32"\n", start, end);
} }
TEST_ASSERT(end > start); TEST_ASSERT(end > start);
TEST_ASSERT(end - start >= 512 * 1024); TEST_ASSERT(end - start >= 512 * 1024);
@@ -83,7 +84,7 @@ static void setup_mmap_tests(void)
for (uint32_t word = 0; word < 1024; ++word) { for (uint32_t word = 0; word < 1024; ++word) {
uint32_t val = rand(); uint32_t val = rand();
if (block == start / 0x10000 && sector == 0 && word == 0) { if (block == start / 0x10000 && sector == 0 && word == 0) {
printf("setup_mmap_tests(): first prepped word: 0x%08x (flash holds 0x%08x)\n", val, buffer[word]); printf("setup_mmap_tests(): first prepped word: 0x%08"PRIx32" (flash holds 0x%08"PRIx32")\n", val, buffer[word]);
} }
if (buffer[word] != val) { if (buffer[word] != val) {
buffer[word] = val; buffer[word] = val;
@@ -101,12 +102,13 @@ static void setup_mmap_tests(void)
TEST_CASE("Can mmap into data address space", "[spi_flash][mmap]") TEST_CASE("Can mmap into data address space", "[spi_flash][mmap]")
{ {
esp_err_t ret = ESP_FAIL;
setup_mmap_tests(); setup_mmap_tests();
printf("Mapping %x (+%x)\n", start, end - start); printf("Mapping %"PRIx32" (+%"PRIx32")\n", start, end - start);
const void *ptr1; const void *ptr1;
TEST_ESP_OK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); TEST_ESP_OK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) );
printf("mmap_res: handle=%d ptr=%p\n", handle1, ptr1); printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle1, ptr1);
spi_flash_mmap_dump(); spi_flash_mmap_dump();
@@ -121,20 +123,22 @@ TEST_CASE("Can mmap into data address space", "[spi_flash][mmap]")
} }
} }
} }
printf("Mapping %x (+%x)\n", start - 0x10000, 0x20000); printf("Mapping %"PRIx32" (+%x)\n", start - 0x10000, 0x20000);
const void *ptr2; const void *ptr2;
TEST_ESP_OK( spi_flash_mmap(start - 0x10000, 0x20000, SPI_FLASH_MMAP_DATA, &ptr2, &handle2) ); TEST_ESP_OK( spi_flash_mmap(start - 0x10000, 0x20000, SPI_FLASH_MMAP_DATA, &ptr2, &handle2) );
printf("mmap_res: handle=%d ptr=%p\n", handle2, ptr2); printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle2, ptr2);
TEST_ASSERT_EQUAL_HEX32(start - 0x10000, spi_flash_cache2phys(ptr2)); TEST_ASSERT_EQUAL_HEX32(start - 0x10000, spi_flash_cache2phys(ptr2));
TEST_ASSERT_EQUAL_PTR(ptr2, spi_flash_phys2cache(start - 0x10000, SPI_FLASH_MMAP_DATA)); TEST_ASSERT_EQUAL_PTR(ptr2, spi_flash_phys2cache(start - 0x10000, SPI_FLASH_MMAP_DATA));
spi_flash_mmap_dump(); spi_flash_mmap_dump();
printf("Mapping %x (+%x)\n", start, 0x10000); printf("Mapping %"PRIx32" (+%x)\n", start, 0x10000);
const void *ptr3; const void *ptr3;
TEST_ESP_OK( spi_flash_mmap(start, 0x10000, SPI_FLASH_MMAP_DATA, &ptr3, &handle3) ); ret = spi_flash_mmap(start, 0x10000, SPI_FLASH_MMAP_DATA, &ptr3, &handle3);
printf("mmap_res: handle=%d ptr=%p\n", handle3, ptr3); printf("ret: 0x%x\n", ret);
TEST_ASSERT(ret == ESP_OK);
printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle3, ptr3);
TEST_ASSERT_EQUAL_HEX32(start, spi_flash_cache2phys(ptr3)); TEST_ASSERT_EQUAL_HEX32(start, spi_flash_cache2phys(ptr3));
TEST_ASSERT_EQUAL_PTR(ptr3, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA)); TEST_ASSERT_EQUAL_PTR(ptr3, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA));
@@ -156,24 +160,24 @@ TEST_CASE("Can mmap into data address space", "[spi_flash][mmap]")
spi_flash_munmap(handle3); spi_flash_munmap(handle3);
handle3 = 0; handle3 = 0;
printf("start corresponding vaddr: 0x%x\n", (int)spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA));
TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA)); TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA));
} }
#if !DISABLED_FOR_TARGETS(ESP32S3, ESP32C3) #if !(CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2)
/* On S3/C3 the cache is programmatically split between Icache and dcache and with the default setup we dont leave a lot pages /* On S3/C3/C2 the cache is programmatically split between Icache and dcache and with the default setup we dont leave a lot pages
available for additional mmaps into instruction space. Disabling this test for now since any hypothetical use case for this available for additional mmaps into instruction space. Disabling this test for now since any hypothetical use case for this
is no longer supported "out of the box" is no longer supported "out of the box"
*/ */
TEST_CASE("Can mmap into instruction address space", "[spi_flash][mmap]") TEST_CASE("Can mmap into instruction address space", "[spi_flash][mmap]")
{ {
setup_mmap_tests(); setup_mmap_tests();
printf("Mapping %x (+%x)\n", start, end - start); printf("Mapping %"PRIx32" (+%"PRIx32")\n", start, end - start);
spi_flash_mmap_handle_t handle1; spi_flash_mmap_handle_t handle1;
const void *ptr1; const void *ptr1;
TEST_ESP_OK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_INST, &ptr1, &handle1) ); TEST_ESP_OK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_INST, &ptr1, &handle1) );
printf("mmap_res: handle=%d ptr=%p\n", handle1, ptr1); printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle1, ptr1);
spi_flash_mmap_dump(); spi_flash_mmap_dump();
@@ -186,22 +190,22 @@ TEST_CASE("Can mmap into instruction address space", "[spi_flash][mmap]")
} }
} }
} }
printf("Mapping %x (+%x)\n", start - 0x10000, 0x20000); printf("Mapping %"PRIx32" (+%x)\n", start - 0x10000, 0x20000);
spi_flash_mmap_handle_t handle2; spi_flash_mmap_handle_t handle2;
const void *ptr2; const void *ptr2;
TEST_ESP_OK( spi_flash_mmap(start - 0x10000, 0x20000, SPI_FLASH_MMAP_INST, &ptr2, &handle2) ); TEST_ESP_OK( spi_flash_mmap(start - 0x10000, 0x20000, SPI_FLASH_MMAP_INST, &ptr2, &handle2) );
printf("mmap_res: handle=%d ptr=%p\n", handle2, ptr2); printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle2, ptr2);
TEST_ASSERT_EQUAL_HEX32(start - 0x10000, spi_flash_cache2phys(ptr2)); TEST_ASSERT_EQUAL_HEX32(start - 0x10000, spi_flash_cache2phys(ptr2));
TEST_ASSERT_EQUAL_PTR(ptr2, spi_flash_phys2cache(start - 0x10000, SPI_FLASH_MMAP_INST)); TEST_ASSERT_EQUAL_PTR(ptr2, spi_flash_phys2cache(start - 0x10000, SPI_FLASH_MMAP_INST));
spi_flash_mmap_dump(); spi_flash_mmap_dump();
printf("Mapping %x (+%x)\n", start, 0x10000); printf("Mapping %"PRIx32" (+%x)\n", start, 0x10000);
spi_flash_mmap_handle_t handle3; spi_flash_mmap_handle_t handle3;
const void *ptr3; const void *ptr3;
TEST_ESP_OK( spi_flash_mmap(start, 0x10000, SPI_FLASH_MMAP_INST, &ptr3, &handle3) ); TEST_ESP_OK( spi_flash_mmap(start, 0x10000, SPI_FLASH_MMAP_INST, &ptr3, &handle3) );
printf("mmap_res: handle=%d ptr=%p\n", handle3, ptr3); printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle3, ptr3);
TEST_ASSERT_EQUAL_HEX32(start, spi_flash_cache2phys(ptr3)); TEST_ASSERT_EQUAL_HEX32(start, spi_flash_cache2phys(ptr3));
TEST_ASSERT_EQUAL_PTR(ptr3, spi_flash_phys2cache(start, SPI_FLASH_MMAP_INST)); TEST_ASSERT_EQUAL_PTR(ptr3, spi_flash_phys2cache(start, SPI_FLASH_MMAP_INST));
@@ -218,11 +222,8 @@ TEST_CASE("Can mmap into instruction address space", "[spi_flash][mmap]")
printf("Unmapping handle3\n"); printf("Unmapping handle3\n");
spi_flash_munmap(handle3); spi_flash_munmap(handle3);
} }
#endif // #if !CONFIG_IDF_TARGET_ESP32C2
#endif //!DISABLED_FOR_TARGETS(ESP32S3, ESP32C3)
TEST_CASE("Can mmap unordered pages into contiguous memory", "[spi_flash][mmap]") TEST_CASE("Can mmap unordered pages into contiguous memory", "[spi_flash][mmap]")
{ {
@@ -239,7 +240,7 @@ TEST_CASE("Can mmap unordered pages into contiguous memory", "[spi_flash][mmap]"
//make inverse mapping: virt 0 -> page (nopages-1), virt 1 -> page (nopages-2), ... //make inverse mapping: virt 0 -> page (nopages-1), virt 1 -> page (nopages-2), ...
for (int i = 0; i < nopages; i++) { for (int i = 0; i < nopages; i++) {
pages[i] = startpage + (nopages - 1) - i; pages[i] = startpage + (nopages - 1) - i;
printf("Offset %x page %d\n", i*0x10000, pages[i]); printf("Offset %x page %d\n", i * SPI_FLASH_MMU_PAGE_SIZE, pages[i]);
} }
printf("Attempting mapping of unordered pages to contiguous memory area\n"); printf("Attempting mapping of unordered pages to contiguous memory area\n");
@@ -247,23 +248,31 @@ TEST_CASE("Can mmap unordered pages into contiguous memory", "[spi_flash][mmap]"
spi_flash_mmap_handle_t handle1; spi_flash_mmap_handle_t handle1;
const void *ptr1; const void *ptr1;
TEST_ESP_OK( spi_flash_mmap_pages(pages, nopages, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); TEST_ESP_OK( spi_flash_mmap_pages(pages, nopages, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) );
printf("mmap_res: handle=%d ptr=%p\n", handle1, ptr1); printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle1, ptr1);
spi_flash_mmap_dump(); spi_flash_mmap_dump();
#if (CONFIG_MMU_PAGE_SIZE == 0x10000)
uint32_t words_per_sector = 1024;
#elif (CONFIG_MMU_PAGE_SIZE == 0x8000)
uint32_t words_per_sector = 512;
#elif (CONFIG_MMU_PAGE_SIZE == 0x4000)
uint32_t words_per_sector = 256;
#else
uint32_t words_per_sector = 128;
#endif
srand(0); srand(0);
const uint32_t *data = (const uint32_t *) ptr1; const uint32_t *data = (const uint32_t *) ptr1;
for (int block = 0; block < nopages; ++block) { for (int block = 0; block < 1; ++block) {
for (int sector = 0; sector < 16; ++sector) { for (int sector = 0; sector < 16; ++sector) {
for (uint32_t word = 0; word < 1024; ++word) { for (uint32_t word = 0; word < words_per_sector; ++word) {
TEST_ASSERT_EQUAL_UINT32(rand(), data[(((nopages-1)-block) * 16 + sector) * 1024 + word]); TEST_ASSERT_EQUAL_UINT32(rand(), data[(((nopages - 1) - block) * 16 + sector) * words_per_sector + word]);
} }
} }
} }
printf("Unmapping handle1\n"); printf("Unmapping handle1\n");
spi_flash_munmap(handle1); spi_flash_munmap(handle1);
spi_flash_mmap_dump();
} }
TEST_CASE("flash_mmap invalidates just-written data", "[spi_flash][mmap]") TEST_CASE("flash_mmap invalidates just-written data", "[spi_flash][mmap]")
@@ -282,7 +291,7 @@ TEST_CASE("flash_mmap invalidates just-written data", "[spi_flash][mmap]")
/* map erased test region to ptr1 */ /* map erased test region to ptr1 */
TEST_ESP_OK( spi_flash_mmap(start, test_size, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); TEST_ESP_OK( spi_flash_mmap(start, test_size, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) );
printf("mmap_res ptr1: handle=%d ptr=%p\n", handle1, ptr1); printf("mmap_res ptr1: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle1, ptr1);
/* verify it's all 0xFF */ /* verify it's all 0xFF */
for (int i = 0; i < test_size; i++) { for (int i = 0; i < test_size; i++) {
@@ -304,7 +313,7 @@ TEST_CASE("flash_mmap invalidates just-written data", "[spi_flash][mmap]")
ensuring we see the updated flash. ensuring we see the updated flash.
*/ */
TEST_ESP_OK( spi_flash_mmap(start, test_size, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); TEST_ESP_OK( spi_flash_mmap(start, test_size, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) );
printf("mmap_res ptr1 #2: handle=%d ptr=%p\n", handle1, ptr1); printf("mmap_res ptr1 #2: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle1, ptr1);
/* assert that ptr1 now maps to the new values on flash, /* assert that ptr1 now maps to the new values on flash,
ie contents of buf array. ie contents of buf array.
@@ -320,10 +329,10 @@ TEST_CASE("flash_mmap can mmap after get enough free MMU pages", "[spi_flash][mm
//this test case should make flash size >= 4MB, because max size of Dcache can mapped is 4MB //this test case should make flash size >= 4MB, because max size of Dcache can mapped is 4MB
setup_mmap_tests(); setup_mmap_tests();
printf("Mapping %x (+%x)\n", start, end - start); printf("Mapping %"PRIx32" (+%"PRIx32")\n", start, end - start);
const void *ptr1; const void *ptr1;
TEST_ESP_OK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); TEST_ESP_OK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) );
printf("mmap_res: handle=%d ptr=%p\n", handle1, ptr1); printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle1, ptr1);
spi_flash_mmap_dump(); spi_flash_mmap_dump();
@@ -344,10 +353,10 @@ TEST_CASE("flash_mmap can mmap after get enough free MMU pages", "[spi_flash][mm
uint32_t flash_pages = flash_size / SPI_FLASH_MMU_PAGE_SIZE; uint32_t flash_pages = flash_size / SPI_FLASH_MMU_PAGE_SIZE;
free_pages = (free_pages > flash_pages) ? flash_pages : free_pages; free_pages = (free_pages > flash_pages) ? flash_pages : free_pages;
printf("Mapping %x (+%x)\n", 0, free_pages * SPI_FLASH_MMU_PAGE_SIZE); printf("Mapping %x (+%"PRIx32")\n", 0, free_pages * SPI_FLASH_MMU_PAGE_SIZE);
const void *ptr2; const void *ptr2;
TEST_ESP_OK( spi_flash_mmap(0, free_pages * SPI_FLASH_MMU_PAGE_SIZE, SPI_FLASH_MMAP_DATA, &ptr2, &handle2) ); TEST_ESP_OK( spi_flash_mmap(0, free_pages * SPI_FLASH_MMU_PAGE_SIZE, SPI_FLASH_MMAP_DATA, &ptr2, &handle2) );
printf("mmap_res: handle=%d ptr=%p\n", handle2, ptr2); printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle2, ptr2);
spi_flash_mmap_dump(); spi_flash_mmap_dump();
@@ -364,7 +373,6 @@ TEST_CASE("flash_mmap can mmap after get enough free MMU pages", "[spi_flash][mm
TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA)); TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA));
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]") TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]")
{ {
@@ -377,7 +385,9 @@ TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]")
uint32_t phys = spi_flash_cache2phys(esp_partition_find); uint32_t phys = spi_flash_cache2phys(esp_partition_find);
TEST_ASSERT_NOT_EQUAL(SPI_FLASH_CACHE2PHYS_FAIL, phys); TEST_ASSERT_NOT_EQUAL(SPI_FLASH_CACHE2PHYS_FAIL, phys);
TEST_ASSERT_EQUAL_PTR(esp_partition_find, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_INST)); TEST_ASSERT_EQUAL_PTR(esp_partition_find, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_INST));
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_DATA)); TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_DATA));
#endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
/* Read the flash @ 'phys' and compare it to the data we get via regular cache access */ /* Read the flash @ 'phys' and compare it to the data we get via regular cache access */
spi_flash_read_maybe_encrypted(phys, buf, sizeof(buf)); spi_flash_read_maybe_encrypted(phys, buf, sizeof(buf));
@@ -393,15 +403,15 @@ TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]")
TEST_ASSERT_NOT_EQUAL(SPI_FLASH_CACHE2PHYS_FAIL, phys); TEST_ASSERT_NOT_EQUAL(SPI_FLASH_CACHE2PHYS_FAIL, phys);
TEST_ASSERT_EQUAL_PTR(&constant_data, TEST_ASSERT_EQUAL_PTR(&constant_data,
spi_flash_phys2cache(phys, SPI_FLASH_MMAP_DATA)); spi_flash_phys2cache(phys, SPI_FLASH_MMAP_DATA));
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_INST)); TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_INST));
#endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
/* Read the flash @ 'phys' and compare it to the data we get via normal cache access */ /* Read the flash @ 'phys' and compare it to the data we get via normal cache access */
spi_flash_read_maybe_encrypted(phys, buf, sizeof(constant_data)); spi_flash_read_maybe_encrypted(phys, buf, sizeof(constant_data));
TEST_ASSERT_EQUAL_HEX8_ARRAY(constant_data, buf, sizeof(constant_data)); TEST_ASSERT_EQUAL_HEX8_ARRAY(constant_data, buf, sizeof(constant_data));
} }
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5138
TEST_CASE("mmap consistent with phys2cache/cache2phys", "[spi_flash][mmap]") TEST_CASE("mmap consistent with phys2cache/cache2phys", "[spi_flash][mmap]")
{ {
const void *ptr = NULL; const void *ptr = NULL;
@@ -470,4 +480,3 @@ TEST_CASE("no stale data read post mmap and write partition", "[spi_flash][mmap]
spi_flash_munmap(handle); spi_flash_munmap(handle);
TEST_ASSERT_EQUAL(0, memcmp(buf, read_data, sizeof(buf))); TEST_ASSERT_EQUAL(0, memcmp(buf, read_data, sizeof(buf)));
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)

View File

@@ -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, , 528K
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
3 nvs, data, nvs, 0x9000, 0x6000,
4 factory, 0, 0, 0x10000, 1M
5 flash_test, data, fat, , 528K

View File

@@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
from pytest_embedded import Dut
@pytest.mark.supported_targets
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
[
'release',
],
indirect=True,
)
def test_flash_mmap(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests')
dut.write('*')
dut.expect_unity_test_output(timeout=120)

View File

@@ -0,0 +1,4 @@
CONFIG_ESP_TASK_WDT=n
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

View File

@@ -0,0 +1,3 @@
CONFIG_ESP_TASK_WDT=n
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"