test(flash_mmap): test flash mmap pages

This commit is contained in:
Armando 2023-07-03 11:46:51 +08:00
parent 6183b555aa
commit 53b1c2a2e6
11 changed files with 244 additions and 0 deletions

View File

@ -378,7 +378,9 @@ TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]")
uint32_t phys = spi_flash_cache2phys(esp_partition_find);
TEST_ASSERT_NOT_EQUAL(SPI_FLASH_CACHE2PHYS_FAIL, phys);
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));
#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 */
spi_flash_read_maybe_encrypted(phys, buf, sizeof(buf));
@ -394,7 +396,9 @@ TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]")
TEST_ASSERT_NOT_EQUAL(SPI_FLASH_CACHE2PHYS_FAIL, phys);
TEST_ASSERT_EQUAL_PTR(&constant_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));
#endif
/* 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));

View File

@ -0,0 +1,6 @@
# 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.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_flash_mmap)

View File

@ -0,0 +1,7 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
This project tests if Flash and PSRAM can work under different configurations.
To add new configuration, create one more sdkconfig.ci.NAME file in this directory.
If you need to test for anything other than flash and psram, create another test project.

View File

@ -0,0 +1,3 @@
idf_component_register(SRCS "test_flash_mmap.c"
INCLUDE_DIRS "."
PRIV_REQUIRES unity spi_flash esp_partition)

View File

@ -0,0 +1,162 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include <sys/queue.h>
#include "sdkconfig.h"
#include "unity.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "esp_flash.h"
#include "esp_partition.h"
#include "spi_flash_mmap.h"
const static char *TAG = "MMAP_TEST";
#define TEST_BLOCK_SIZE CONFIG_MMU_PAGE_SIZE
typedef struct test_block_info_ {
uint32_t vaddr;
spi_flash_mmap_handle_t handle;
LIST_ENTRY(test_block_info_) entries;
} test_block_info_t;
static LIST_HEAD(test_block_list_head_, test_block_info_) test_block_head;
static DRAM_ATTR uint8_t sector_buf[TEST_BLOCK_SIZE];
static const esp_partition_t *s_get_partition(void)
{
//Find the "storage1" partition defined in `partitions.csv`
const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage1");
if (!result) {
ESP_LOGE(TAG, "Can't find the partition, please define it correctly in `partitions.csv`");
abort();
}
return result;
}
static void s_fill_random_data(uint8_t *buffer, size_t size, int random_seed)
{
srand(random_seed);
for (int i = 0 ; i < size; i++) {
buffer[i] = rand() % 0xff;
}
}
static bool s_test_mmap_data_by_random(uint8_t *mblock_ptr, size_t size, int random_seed)
{
srand(random_seed);
uint8_t *test_ptr = mblock_ptr;
for (int i = 0; i < size; i++) {
uint8_t test_data = rand() % 0xff;
if(test_data != test_ptr[i]) {
printf("i: %d\n", i);
printf("test_data: %d\n", test_data);
printf("test_ptr[%d]: %d\n", i, test_ptr[i]);
printf("sector_buf[%d]: %d\n", i, sector_buf[i]);
ESP_EARLY_LOGE(TAG, "FAIL!!!!!!");
return false;
}
}
return true;
}
static void s_print_free_pages(void)
{
uint32_t free_i_pages = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_INST);
uint32_t free_d_pages = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
printf("free_i_pages: 0d%"PRId32"\n", free_i_pages);
printf("free_d_pages: 0d%"PRId32"\n", free_d_pages);
}
void app_main(void)
{
//Get the partition used for SPI1 erase operation
const esp_partition_t *part = s_get_partition();
ESP_LOGI(TAG, "found partition '%s' at offset 0x%"PRIx32" with size 0x%"PRIx32, part->label, part->address, part->size);
//Erase whole region
TEST_ESP_OK(esp_flash_erase_region(part->flash_chip, part->address, part->size));
ESP_LOGI(TAG, "TEST_BLOCK_SIZE: 0x%x", TEST_BLOCK_SIZE);
s_print_free_pages();
uint32_t offset = 0;
int test_seed = 299;
while (1) {
s_fill_random_data(sector_buf, sizeof(sector_buf), test_seed);
ESP_LOGI(TAG, "rand seed: %d, write flash addr: %p...", test_seed, (void *)(part->address + offset));
TEST_ESP_OK(esp_flash_write(part->flash_chip, sector_buf, (part->address + offset), sizeof(sector_buf)));
test_seed++;
offset += TEST_BLOCK_SIZE;
if (offset == part->size) {
break;
}
}
esp_err_t ret = ESP_FAIL;
int count = 0;
LIST_INIT(&test_block_head);
offset = 0;
test_seed = 299;
while (1) {
test_block_info_t *block_info = heap_caps_calloc(1, sizeof(test_block_info_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
TEST_ASSERT(block_info && "no mem");
spi_flash_mmap_handle_t handle;
const void *ptr = NULL;
ret = spi_flash_mmap(part->address + offset, TEST_BLOCK_SIZE, SPI_FLASH_MMAP_DATA, &ptr, &handle);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "ptr is %p", ptr);
s_fill_random_data(sector_buf, sizeof(sector_buf), test_seed);
bool success = s_test_mmap_data_by_random((uint8_t *)ptr, sizeof(sector_buf), test_seed);
TEST_ASSERT(success);
} else if (ret == ESP_ERR_NOT_FOUND) {
free(block_info);
break;
} else {
ESP_LOGE(TAG, "ret: 0x%x", ret);
TEST_ASSERT(false);
}
block_info->vaddr = (uint32_t)ptr;
block_info->handle = handle;
LIST_INSERT_HEAD(&test_block_head, block_info, entries);
count++;
test_seed++;
offset += TEST_BLOCK_SIZE;
if (offset == part->size) {
break;
}
}
ESP_LOGI(TAG, "no more free block / free flash size, finish test, test block size: 0x%x, count: 0d%d", TEST_BLOCK_SIZE, count);
s_print_free_pages();
test_block_info_t *block_to_free = LIST_FIRST(&test_block_head);
test_block_info_t *temp = NULL;
while (block_to_free) {
temp = block_to_free;
spi_flash_munmap(block_to_free->handle);
block_to_free = LIST_NEXT(block_to_free, entries);
free(temp);
}
s_print_free_pages();
printf("flash mmap test success\n");
}

View File

@ -0,0 +1,6 @@
# 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,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
storage1, data, fat, , 896K,
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 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 1M,
6 storage1, data, fat, , 896K,

View File

@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import os
import pathlib
import pytest
from pytest_embedded import Dut
# For F4R8 board (Quad Flash and Octal PSRAM)
MSPI_F4R8_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.f4r8*')]
@pytest.mark.esp32s3
@pytest.mark.MSPI_F4R8
@pytest.mark.parametrize('config', MSPI_F4R8_configs, indirect=True)
def test_mmap_flash4_psram8(dut: Dut) -> None:
dut.expect_exact('flash mmap test success', timeout=300)
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.parametrize('config', [
'psram',
], indirect=True)
def test_mmap_psram(dut: Dut) -> None:
dut.expect_exact('flash mmap test success', timeout=300)
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.parametrize('config', [
'release',
], indirect=True)
def test_mmap(dut: Dut) -> None:
dut.expect_exact('flash mmap test success', timeout=300)

View File

@ -0,0 +1,7 @@
# F4R8, Flash 80M SDR, PSRAM 80M DDR
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_SPEED_80M=y

View File

@ -0,0 +1 @@
CONFIG_SPIRAM=y

View File

@ -0,0 +1,3 @@
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

View File

@ -0,0 +1,5 @@
CONFIG_ESP_TASK_WDT_EN=n
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"