feat(storage/fatfs): add dynamic buffer usage test

This commit is contained in:
Tomáš Rohlínek
2025-01-24 13:56:37 +01:00
parent 82dac1f1bd
commit b1997ebab6
13 changed files with 175 additions and 1 deletions

View File

@@ -1,5 +1,13 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/fatfs/test_apps/dyn_buffers:
disable_test:
- if: IDF_TARGET != "esp32"
reason: only one target required
depends_components:
- fatfs
components/fatfs/test_apps/flash_ro:
disable_test:
- if: IDF_TARGET not in ["esp32", "esp32c3"]

View File

@@ -1,3 +1,6 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
# fatfs component target tests
This directory contains tests for `fatfs` component which are run on chip targets.
@@ -9,6 +12,7 @@ Fatfs tests can be executed with different `diskio` backends: `diskio_sdmmc` (SD
- [sdcard](sdcard/) — runs fatfs tests with an SD card over SDMMC or SDSPI interface
- [flash_wl](flash_wl/) - runs fatfs test in a wear_levelling partition in SPI flash
- [flash_ro](flash_ro/) - runs fatfs test in a read-only (no wear levelling) partition in SPI flash
- [dyn_buffers](dyn_buffers/) - check if enabling dynamic buffers in FATFS has an effect
These test apps define:
- test functions

View File

@@ -0,0 +1,7 @@
# The following five 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)
idf_build_set_property(MINIMAL_BUILD ON)
project(dyn_buffers)

View File

@@ -0,0 +1,8 @@
| 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 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
This test app checks if `CONFIG_FATFS_USE_DYN_BUFFERS` has any effect.
These tests should be possible to run on any ESP development board, not extra hardware is necessary.
See [../README.md](../README.md) for more information about FATFS test apps.

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "test_fatfs_dyn_buffers.c"
INCLUDE_DIRS "."
REQUIRES wear_levelling fatfs vfs)

View File

@@ -0,0 +1,101 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include "wear_levelling.h"
#include "esp_partition.h"
#include "esp_vfs.h"
#include "esp_vfs_fat.h"
#include "esp_heap_caps.h"
#include "sdkconfig.h"
#include "ff.h"
#include "esp_debug_helpers.h"
static const char* TAG = "Test dynamic buffers";
static volatile bool g_alloc_count_enable = false;
static volatile int g_buffer_alloc_count = 0;
static esp_vfs_fat_mount_config_t g_mount_config = {
.format_if_mount_failed = true,
.max_files = 5,
};
void esp_heap_trace_alloc_hook(void* ptr, size_t size, uint32_t caps)
{
(void) ptr;
(void) caps;
if (!g_alloc_count_enable) {
return;
}
// This will work only on SPI flash
// Different flash types might break this check
if (size == FF_MAX_SS) {
g_buffer_alloc_count++;
}
}
void app_main(void)
{
esp_err_t err = ESP_OK;
wl_handle_t wl_handle;
err = esp_vfs_fat_spiflash_format_cfg_rw_wl("/spiflash", NULL, &g_mount_config);
ESP_LOGI(TAG, "Mounting FATFS");
g_mount_config.format_if_mount_failed = false,
g_alloc_count_enable = true;
err = esp_vfs_fat_spiflash_mount_rw_wl("/spiflash", NULL, &g_mount_config, &wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "FATFS mount failed with error: %d", err);
return;
}
ESP_LOGI(TAG, "Mounted");
int fd = open("/spiflash/test.txt", O_RDWR|O_CREAT);
if (fd < 0) {
ESP_LOGE(TAG, "Failed opening file");
}
close(fd);
g_alloc_count_enable = false;
ESP_LOGI(TAG, "Unmounting FATFS");
esp_vfs_fat_spiflash_unmount_rw_wl("/spiflash", wl_handle);
ESP_LOGI(TAG, "Unmounted");
ESP_LOGI(TAG, "Allocs called:\n\tBuffer: %d"
, g_buffer_alloc_count);
#if CONFIG_FATFS_USE_DYN_BUFFERS
if (g_buffer_alloc_count != 2) {
ESP_LOGE(TAG, "FATFS buffer should have been allocated once for each context (file and fatfs)");
return;
}
#else
if (g_buffer_alloc_count != 0) {
ESP_LOGE(TAG, "FATFS buffer should not have been allocated");
return;
}
#endif
ESP_LOGI(TAG, "Done");
}

View File

@@ -0,0 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
factory, app, factory, 0x10000, 768k,
storage, data, fat, , 528k,
storage2, data, fat, , 528k,
storage1, data, fat, , 32k,
1 # Name Type SubType Offset Size Flags
2 factory app factory 0x10000 768k
3 storage data fat 528k
4 storage2 data fat 528k
5 storage1 data fat 32k

View File

@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
[
'dyn_buffers',
'no_dyn_buffers',
],
)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_fatfs_flash_dyn_buffers(config: str, dut: Dut) -> None:
dut.expect('Mounting FATFS')
dut.expect('Mounted')
dut.expect('Unmounting FATFS')
dut.expect('Unmounted')
dut.expect('Done')

View File

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

View File

@@ -0,0 +1,14 @@
# General options for additional checks
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
CONFIG_COMPILER_WARN_WRITE_STRINGS=y
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
CONFIG_COMPILER_STACK_CHECK=y
# use custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
# to measure allocations
CONFIG_HEAP_USE_HOOKS=y

View File

@@ -13,7 +13,7 @@ from pytest_embedded_idf.utils import idf_parametrize
'release',
'fastseek',
'auto_fsync',
'no_dyn_buffers',
'dyn_buffers',
],
)
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])

View File

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