mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(fatfs): fix a memory leak bug when FF_USE_DYN_BUFFER was enabled
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
idf_component_register(SRCS "test_fatfs_dyn_buffers.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES wear_levelling fatfs vfs)
|
||||
REQUIRES unity wear_levelling fatfs vfs)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -7,10 +7,14 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include "unity.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "wear_levelling.h"
|
||||
#include "diskio_wl.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_vfs.h"
|
||||
#include "esp_vfs_fat.h"
|
||||
#include "vfs_fat_internal.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "ff.h"
|
||||
@@ -21,10 +25,19 @@ 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,
|
||||
};
|
||||
// Some resources are lazy allocated, the threshold is left for that case
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (1280)
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
unity_utils_record_free_mem();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
esp_partition_unload_all(); //clean up some of the esp_partition's allocations
|
||||
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
|
||||
}
|
||||
|
||||
void esp_heap_trace_alloc_hook(void* ptr, size_t size, uint32_t caps)
|
||||
{
|
||||
@@ -42,32 +55,28 @@ void esp_heap_trace_alloc_hook(void* ptr, size_t size, uint32_t caps)
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
TEST_CASE("(dyn_buffers) basic mounting and file operations", "[fatfs][dyn_buffers]")
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_vfs_fat_mount_config_t mount_config = {
|
||||
.format_if_mount_failed = true,
|
||||
.max_files = 5,
|
||||
};
|
||||
|
||||
wl_handle_t wl_handle;
|
||||
|
||||
err = esp_vfs_fat_spiflash_format_cfg_rw_wl("/spiflash", NULL, &g_mount_config);
|
||||
esp_vfs_fat_spiflash_format_cfg_rw_wl("/spiflash", NULL, &mount_config);
|
||||
|
||||
ESP_LOGI(TAG, "Mounting FATFS");
|
||||
|
||||
g_mount_config.format_if_mount_failed = false,
|
||||
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;
|
||||
}
|
||||
TEST_ESP_OK(esp_vfs_fat_spiflash_mount_rw_wl("/spiflash", NULL, &mount_config, &wl_handle));
|
||||
|
||||
ESP_LOGI(TAG, "Mounted");
|
||||
|
||||
int fd = open("/spiflash/test.txt", O_RDWR|O_CREAT);
|
||||
if (fd < 0) {
|
||||
ESP_LOGE(TAG, "Failed opening file");
|
||||
}
|
||||
TEST_ASSERT(fd >= 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
@@ -83,19 +92,66 @@ void app_main(void)
|
||||
, 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;
|
||||
}
|
||||
TEST_ASSERT_MESSAGE(g_buffer_alloc_count == 2, "FATFS buffer should have been allocated once for each context (file and fatfs)");
|
||||
#else
|
||||
|
||||
if (g_buffer_alloc_count != 0) {
|
||||
ESP_LOGE(TAG, "FATFS buffer should not have been allocated");
|
||||
return;
|
||||
}
|
||||
|
||||
TEST_ASSERT_MESSAGE(g_buffer_alloc_count == 0, "FATFS buffer should not have been allocated");
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Done");
|
||||
}
|
||||
|
||||
TEST_CASE("(dyn_buffers) File system data does not exist, format and remount", "[fatfs][dyn_buffers]")
|
||||
{
|
||||
const char test_par_lab[] = "storage2";
|
||||
|
||||
const esp_partition_t * part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, test_par_lab);
|
||||
TEST_ASSERT(part != NULL);
|
||||
esp_partition_erase_range(part, 0, part->size);
|
||||
|
||||
|
||||
esp_vfs_fat_mount_config_t mount_config = {
|
||||
.format_if_mount_failed = true,
|
||||
.max_files = 5,
|
||||
};
|
||||
wl_handle_t wl_handle;
|
||||
TEST_ESP_OK(esp_vfs_fat_spiflash_mount_rw_wl("/spiflash2", test_par_lab, &mount_config, &wl_handle));
|
||||
|
||||
esp_vfs_fat_spiflash_unmount_rw_wl("/spiflash2", wl_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("(dyn_buffers) Unmount and then close the file", "[fatfs][dyn_buffers]")
|
||||
{
|
||||
const char test_par_lab[] = "storage2";
|
||||
|
||||
esp_vfs_fat_mount_config_t mount_config = {
|
||||
.format_if_mount_failed = true,
|
||||
.max_files = 5,
|
||||
};
|
||||
wl_handle_t wl_handle;
|
||||
TEST_ESP_OK(esp_vfs_fat_spiflash_mount_rw_wl("/spiflash2", test_par_lab, &mount_config, &wl_handle));
|
||||
BYTE pdrv = ff_diskio_get_pdrv_wl(wl_handle);
|
||||
char drv[3] = {(char)('0' + pdrv), ':', 0};
|
||||
|
||||
vfs_fat_spiflash_ctx_t *ctx = get_vfs_fat_spiflash_ctx(wl_handle);
|
||||
TEST_ASSERT_NOT_NULL(ctx);
|
||||
FATFS *fs = ctx->fs;
|
||||
TEST_ASSERT_NOT_NULL(fs);
|
||||
|
||||
int fd = open("/spiflash2/test.txt", O_RDWR|O_CREAT);
|
||||
TEST_ASSERT(fd >= 0);
|
||||
// Unmount fatfs only
|
||||
f_mount(0, drv, 0);
|
||||
close(fd);
|
||||
|
||||
f_mount(fs, drv, 1);
|
||||
fd = open("/spiflash2/test.txt", O_RDWR|O_CREAT);
|
||||
TEST_ASSERT(fd >= 0);
|
||||
// Unmount fatfs and vfs
|
||||
esp_vfs_fat_spiflash_unmount_rw_wl("/spiflash2", wl_handle);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
unity_run_menu();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
@@ -15,8 +15,4 @@ from pytest_embedded_idf.utils import idf_parametrize
|
||||
)
|
||||
@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')
|
||||
dut.run_all_single_board_cases(timeout=30)
|
||||
|
||||
Reference in New Issue
Block a user