Merge branch 'feature/fatfs_allocation_unit_size' into 'master'
fatfs: add option to set allocation unit size See merge request idf/esp-idf!1760
This commit is contained in:
commit
56843281c7
8 changed files with 87 additions and 15 deletions
|
@ -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
|
||||
|
|
30
components/fatfs/src/vfs_fat_internal.h
Normal file
30
components/fatfs/src/vfs_fat_internal.h
Normal 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;
|
||||
}
|
|
@ -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"
|
||||
|
@ -112,16 +113,23 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
|
|||
goto fail;
|
||||
}
|
||||
ESP_LOGW(TAG, "partitioning card");
|
||||
DWORD plist[] = {100, 0, 0, 0};
|
||||
workbuf = malloc(workbuf_size);
|
||||
if (workbuf == NULL) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto fail;
|
||||
}
|
||||
DWORD plist[] = {100, 0, 0, 0};
|
||||
res = f_fdisk(s_pdrv, plist, workbuf);
|
||||
if (res != FR_OK) {
|
||||
err = ESP_FAIL;
|
||||
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);
|
||||
|
|
|
@ -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,15 @@ 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);
|
||||
if (workbuf == NULL) {
|
||||
result = ESP_ERR_NO_MEM;
|
||||
goto fail;
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# SD Card example
|
||||
# Wear levelling example
|
||||
|
||||
This example demonstrates how to use wear levelling library and FATFS library to store files in a partition inside SPI flash. Example does the following steps:
|
||||
|
||||
|
@ -15,9 +15,14 @@ This example demonstrates how to use wear levelling library and FATFS library to
|
|||
Here is an typical example console output.
|
||||
|
||||
```
|
||||
Try to open file ...
|
||||
I (239) wear_level: Reading file
|
||||
Read from file: 'Hello User! I'm happy to see you!1'
|
||||
W (239) wear_levelling: wl_unmount Delete driver
|
||||
I (280) example: Mounting FAT filesystem
|
||||
W (440) vfs_fat_spiflash: f_mount failed (13)
|
||||
I (440) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=4096
|
||||
I (660) vfs_fat_spiflash: Mounting again
|
||||
I (660) example: Opening file
|
||||
I (910) example: File written
|
||||
I (910) example: Reading file
|
||||
I (920) example: Read from file: 'written using ESP-IDF v3.1-dev-171-gf9ad17eee-dirty'
|
||||
I (920) example: Unmounting FAT filesystem
|
||||
I (1000) example: Done
|
||||
```
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue