test(flash_mmap): test flash mmap pages

This commit is contained in:
Armando 2023-07-03 16:08:59 +08:00 committed by Armando (Dou Yiwen)
parent 7911e997ff
commit 45877f3176
12 changed files with 267 additions and 12 deletions

View File

@ -363,7 +363,6 @@ test_app_test_003:
test_app_test_004: test_app_test_004:
extends: .test_app_esp32s2_template extends: .test_app_esp32s2_template
parallel: 2
tags: tags:
- ESP32S2 - ESP32S2
- Example_GENERIC - Example_GENERIC
@ -407,17 +406,11 @@ test_app_test_flash_psram_f8r8:
- ESP32S3 - ESP32S3
- MSPI_F8R8 - MSPI_F8R8
test_app_test_xip_psram_esp32s2: test_app_test_flash_psram_esp32:
extends: .test_app_esp32s2_template extends: .test_app_esp32_template
tags: tags:
- ESP32S2 - ESP32
- Example_GENERIC - psram
test_app_test_xip_psram_esp32s3:
extends: .test_app_esp32s3_template
tags:
- ESP32S3
- MSPI_F4R8
.component_ut_template: .component_ut_template:
extends: .target_test_job_template extends: .target_test_job_template

View File

@ -3,11 +3,12 @@ COMPONENT_SRCDIRS := patches .
COMPONENT_OBJEXCLUDE := patches/esp_rom_cache_writeback_esp32s3.o COMPONENT_OBJEXCLUDE := patches/esp_rom_cache_writeback_esp32s3.o
COMPONENT_OBJEXCLUDE += patches/esp_rom_mmap.o
ifdef IS_BOOTLOADER_BUILD ifdef IS_BOOTLOADER_BUILD
COMPONENT_OBJEXCLUDE += patches/esp_rom_longjmp.o COMPONENT_OBJEXCLUDE += patches/esp_rom_longjmp.o
endif endif
COMPONENT_OBJEXCLUDE := patches/esp_rom_mmap.o
#Linker scripts used to link the final application. #Linker scripts used to link the final application.
#Warning: These linker scripts are only used when the normal app is compiled; the bootloader #Warning: These linker scripts are only used when the normal app is compiled; the bootloader

View File

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(flash_mmap_test)

View File

@ -0,0 +1,4 @@
| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- |
This test app is used to test flash mmap with PSRAM

View File

@ -0,0 +1,56 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import glob
import os
from typing import Any
import ttfw_idf
from tiny_test_fw import Utility
def test_func(env, dut): # type: (Any, Any) -> None
dut.start_app()
dut.expect('success', timeout=60)
env.close_dut(dut.name)
def test_loop(env, config_names): # type: (Any, Any) -> None
for name in config_names:
Utility.console_log("Checking config \"{}\"... ".format(name), end='')
dut = env.get_dut('flash_mmap', 'tools/test_apps/system/flash_mmap', app_config_name=name)
test_func(env, dut)
Utility.console_log('done')
@ttfw_idf.idf_custom_test(env_tag='MSPI_F4R8', target=['esp32s3'])
def test_mmap_esp32s3(env, _): # type: (Any, Any) -> None
config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.esp32s3_f4r8*'))
config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files]
test_loop(env, config_names)
@ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', target=['esp32s2'])
def test_mmap_esp32s2(env, _): # type: (Any, Any) -> None
config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.esp32s2_*'))
config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files]
test_loop(env, config_names)
@ttfw_idf.idf_custom_test(env_tag='psram', target=['esp32'])
def test_mmap_esp32(env, _): # type: (Any, Any) -> None
config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.esp32_*'))
config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files]
test_loop(env, config_names)
if __name__ == '__main__':
test_mmap_esp32s3()
test_mmap_esp32s2()
test_mmap_esp32()

View File

@ -0,0 +1,5 @@
idf_build_get_property(target IDF_TARGET)
set(srcs "test_flash_mmap.c")
idf_component_register(SRCS ${srcs})

View File

@ -0,0 +1,163 @@
/*
* 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 <inttypes.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 "esp_spi_flash.h"
const static char *TAG = "MMAP_TEST";
#define TEST_BLOCK_SIZE 0x10000
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,3 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_ESP32_SPIRAM_SUPPORT=y

View File

@ -0,0 +1,5 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_ESP32S2_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
CONFIG_SPIRAM_RODATA=y

View File

@ -0,0 +1,10 @@
# F4R8, Flash 80M SDR, PSRAM 80M DDR
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_SPEED_80M=y
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
CONFIG_SPIRAM_RODATA=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"