fatfs: add configuration of allocation unit size

Closes https://github.com/espressif/esp-idf/issues/1382.
This commit is contained in:
Ivan Grokhotkov 2018-01-08 16:21:02 +08:00
parent e381c6adde
commit 59859fa53c
7 changed files with 67 additions and 8 deletions

View file

@ -88,8 +88,26 @@ esp_err_t esp_vfs_fat_unregister_path(const char* base_path);
* @brief Configuration arguments for esp_vfs_fat_sdmmc_mount and esp_vfs_fat_spiflash_mount functions
*/
typedef struct {
bool format_if_mount_failed; ///< If FAT partition can not be mounted, and this parameter is true, create partition table and format the filesystem
/**
* If FAT partition can not be mounted, and this parameter is true,
* create partition table and format the filesystem.
*/
bool format_if_mount_failed;
int max_files; ///< Max number of open files
/**
* If format_if_mount_failed is set, and mount fails, format the card
* with given allocation unit size. Must be a power of 2, between sector
* size and 128 * sector size.
* For SD cards, sector size is always 512 bytes. For wear_levelling,
* sector size is determined by CONFIG_WL_SECTOR_SIZE option.
*
* Using larger allocation unit size will result in higher read/write
* performance and higher overhead when storing small files.
*
* Setting this field to 0 will result in allocation unit set to the
* sector size.
*/
size_t allocation_unit_size;
} esp_vfs_fat_mount_config_t;
// Compatibility definition

View file

@ -0,0 +1,30 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "esp_vfs_fat.h"
#include <sys/param.h>
#include <stddef.h>
static inline size_t esp_vfs_fat_get_allocation_unit_size(
size_t sector_size, size_t requested_size)
{
size_t alloc_unit_size = requested_size;
const size_t max_sectors_per_cylinder = 128;
const size_t max_size = sector_size * max_sectors_per_cylinder;
alloc_unit_size = MAX(alloc_unit_size, sector_size);
alloc_unit_size = MIN(alloc_unit_size, max_size);
return alloc_unit_size;
}

View file

@ -17,6 +17,7 @@
#include "esp_log.h"
#include "esp_vfs.h"
#include "esp_vfs_fat.h"
#include "vfs_fat_internal.h"
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#include "sdmmc_cmd.h"
@ -120,8 +121,11 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
ESP_LOGD(TAG, "f_fdisk failed (%d)", res);
goto fail;
}
ESP_LOGW(TAG, "formatting card");
res = f_mkfs(drv, FM_ANY, s_card->csd.sector_size, workbuf, workbuf_size);
size_t alloc_unit_size = esp_vfs_fat_get_allocation_unit_size(
s_card->csd.sector_size,
mount_config->allocation_unit_size);
ESP_LOGW(TAG, "formatting card, allocation unit size=%d", alloc_unit_size);
res = f_mkfs(drv, FM_ANY, alloc_unit_size, workbuf, workbuf_size);
if (res != FR_OK) {
err = ESP_FAIL;
ESP_LOGD(TAG, "f_mkfs failed (%d)", res);

View file

@ -17,6 +17,7 @@
#include "esp_log.h"
#include "esp_vfs.h"
#include "esp_vfs_fat.h"
#include "vfs_fat_internal.h"
#include "diskio.h"
#include "wear_levelling.h"
@ -78,8 +79,11 @@ esp_err_t esp_vfs_fat_spiflash_mount(const char* base_path,
goto fail;
}
workbuf = malloc(workbuf_size);
ESP_LOGI(TAG, "Formatting FATFS partition");
fresult = f_mkfs(drv, FM_ANY | FM_SFD, workbuf_size, workbuf, workbuf_size);
size_t alloc_unit_size = esp_vfs_fat_get_allocation_unit_size(
CONFIG_WL_SECTOR_SIZE,
mount_config->allocation_unit_size);
ESP_LOGI(TAG, "Formatting FATFS partition, allocation unit size=%d", alloc_unit_size);
fresult = f_mkfs(drv, FM_ANY | FM_SFD, alloc_unit_size, workbuf, workbuf_size);
if (fresult != FR_OK) {
result = ESP_FAIL;
ESP_LOGE(TAG, "f_mkfs failed (%d)", fresult);

View file

@ -185,7 +185,8 @@ static void speed_test(void* buf, size_t buf_size, size_t file_size, bool write)
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = write,
.max_files = 5
.max_files = 5,
.allocation_unit_size = 64 * 1024
};
TEST_ESP_OK(esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, NULL));

View file

@ -81,7 +81,8 @@ void app_main(void)
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 5
.max_files = 5,
.allocation_unit_size = 16 * 1024
};
// Use settings defined above to initialize SD card and mount FAT filesystem.

View file

@ -32,7 +32,8 @@ void app_main(void)
// and allow format partition in case if it is new one and was not formated before
const esp_vfs_fat_mount_config_t mount_config = {
.max_files = 4,
.format_if_mount_failed = true
.format_if_mount_failed = true,
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE
};
esp_err_t err = esp_vfs_fat_spiflash_mount(base_path, "storage", &mount_config, &s_wl_handle);
if (err != ESP_OK) {