1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #14430 from benpicco/pkg/fatfs_format

pkg/fatfs: fatfs_vfs: wire up format()
This commit is contained in:
benpicco 2022-02-16 17:22:19 +01:00 committed by GitHub
commit 22a3fc7e8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 88 additions and 44 deletions

View File

@ -36,6 +36,7 @@ USEMODULE += vfs
USEMODULE += littlefs2
# USEMODULE += spiffs
# USEMODULE += fatfs_vfs
# USEMODULE += fatfs_vfs_format
USEMODULE += constfs
# USEMODULE += devfs

View File

@ -7,8 +7,8 @@ application.
In particular, this example shows:
- how to mount/format/unmount a file system, either with spiffs, littlefs or
constfs
- how to mount/format/unmount a file system, either with spiffs, littlefs, fatfs
or constfs
- how to open/read/write/close a file with and without newlib
In RIOT, most file systems use a `mtd` as flash interface. So to use this
@ -76,45 +76,3 @@ Hello World!
cat /const/hello-riot
Hello RIOT!
```
## Example on `native` with `fatfs`
- Unpack the provided image proviced in the `pkg_fatfs` test:
```
$ tar vxjf ../../tests/pkg_fatfs/riot_fatfs_disk.tar.bz2
riot_fatfs_disk.img
```
- Configure the application to use the file and the right geometry by adding
these to the Makefile:
```
CFLAGS += -DMTD_NATIVE_FILENAME=\"riot_fatfs_disk.img\"
CFLAGS += -DMTD_SECTOR_NUM=262144
```
- In the Makefile, comment the `littlefs2` USEMODULE line, and enable the
`fatfs_vfs` line instead.
- Build and run the `filesystem` example application on the `native` target as above.
- Mount the external file system:
```
> mount
mount
/sda successfully mounted
```
- List the available files in the FAT partition:
```
> ls /sda
ls /sda
TEST.TXT
total 1 files
```
- You can also use the writing commands now to create and modify files; run
`vfs` for instructions.

View File

@ -62,6 +62,7 @@ PSEUDOMODULES += event_timeout
PSEUDOMODULES += event_timeout_ztimer
PSEUDOMODULES += evtimer_mbox
PSEUDOMODULES += evtimer_on_ztimer
PSEUDOMODULES += fatfs_vfs_format
PSEUDOMODULES += fmt_%
PSEUDOMODULES += gcoap_dtls
PSEUDOMODULES += fido2_tests

View File

@ -1,5 +1,9 @@
USEMODULE += fatfs_diskio_mtd
USEMODULE += mtd
ifneq (,$(filter vfs_auto_format,$(USEMODULE)))
DEFAULT_MODULE += fatfs_vfs_format
endif
# Use RTC for timestamps if available
FEATURES_OPTIONAL += periph_rtc

View File

@ -167,6 +167,8 @@ DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
*/
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
{
(void)buff;
if ((pdrv >= FF_VOLUMES) || (fatfs_mtd_devs[pdrv]->driver == NULL)) {
return RES_PARERR;
}

View File

@ -23,6 +23,7 @@
#include <errno.h>
#include <inttypes.h>
#include <sys/stat.h> /* for struct stat */
#include <stdlib.h>
#include <string.h>
#include "fs/fatfs.h"
@ -32,6 +33,8 @@
#define ENABLE_DEBUG 0
#include <debug.h>
#define TEST_FATFS_MAX_VOL_STR_LEN 14 /* "-2147483648:/\0" */
static int fatfs_err_to_errno(int32_t err);
static void _fatfs_time_to_timespec(WORD fdate, WORD ftime, time_t *time);
@ -67,6 +70,41 @@ static int _init(vfs_mount_t *mountp)
return -1;
}
#ifdef MODULE_FATFS_VFS_FORMAT
static int _format(vfs_mount_t *mountp)
{
fatfs_desc_t *fs_desc = mountp->private_data;
char volume_str[TEST_FATFS_MAX_VOL_STR_LEN];
#if CONFIG_FATFS_FORMAT_ALLOC_STATIC
static BYTE work[FF_MAX_SS];
static mutex_t work_mtx;
mutex_lock(&work_mtx);
#else
BYTE *work = malloc(FF_MAX_SS);
if (work == NULL) {
return -ENOMEM;
}
#endif
const MKFS_PARM param = {
.fmt = CONFIG_FATFS_FORMAT_TYPE,
};
snprintf(volume_str, sizeof(volume_str), "%u:/", fs_desc->vol_idx);
FRESULT res = f_mkfs(volume_str, &param, work, FF_MAX_SS);
#if CONFIG_FATFS_FORMAT_ALLOC_STATIC
mutex_unlock(&work_mtx);
#else
free(work);
#endif
return fatfs_err_to_errno(res);
}
#endif
static int _mount(vfs_mount_t *mountp)
{
/* if one of the lines below fail to compile you probably need to adjust
@ -515,6 +553,9 @@ static int fatfs_err_to_errno(int32_t err)
}
static const vfs_file_system_ops_t fatfs_fs_ops = {
#ifdef MODULE_FATFS_VFS_FORMAT
.format = _format,
#endif
.mount = _mount,
.umount = _umount,
.rename = _rename,

View File

@ -51,7 +51,11 @@
#ifndef FATFS_FFCONF_OPT_USE_MKFS
#if defined(MODULE_FATFS_VFS) && !defined(MODULE_FATFS_VFS_FORMAT)
#define FF_USE_MKFS 0
#else
#define FF_USE_MKFS 1
#endif
#else
#define FF_USE_MKFS FATFS_FFCONF_OPT_USE_MKFS
#endif/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */

View File

@ -41,6 +41,28 @@ extern "C" {
/** 0:mount on first file access, 1 mount in f_mount() call */
#define FATFS_MOUNT_OPT (1)
/** FAT filesystem type that a file system should be formatted in by vfs_format() */
#ifndef CONFIG_FATFS_FORMAT_TYPE
#if FF_FS_EXFAT
#define CONFIG_FATFS_FORMAT_TYPE FM_EXFAT
#else
#define CONFIG_FATFS_FORMAT_TYPE FM_ANY
#endif
#endif
/**
* @brief Statically allocate work buffer for format operation
*
* This will statically allocate 512 bytes as the work buffer for
* the format operation.
*
* If this is set to 0, dynamic allocation (malloc) will be used
* instead and format will fail if not enough memory is available.
*/
#ifndef CONFIG_FATFS_FORMAT_ALLOC_STATIC
#define CONFIG_FATFS_FORMAT_ALLOC_STATIC 0
#endif
/**
* @brief Size of path buffer for absolute paths
*

View File

@ -4,6 +4,9 @@ USEMODULE += fatfs_vfs
FEATURES_OPTIONAL += periph_rtc
FEATURES_REQUIRED += periph_spi
# remove this if you don't want to format your SD card
USEMODULE += fatfs_vfs_format
FATFS_IMAGE_FILE_SIZE_MIB ?= 128
ifeq ($(BOARD),native)

View File

@ -80,6 +80,13 @@ static void print_test_result(const char *test_name, int ok)
printf("%s:[%s]\n", test_name, ok ? "OK" : "FAILED");
}
static void test_format(void)
{
#ifdef MODULE_FATFS_VFS_FORMAT
print_test_result("test_format__format", vfs_format(&_test_vfs_mount) == 0);
#endif
}
static void test_mount(void)
{
print_test_result("test_mount__mount", vfs_mount(&_test_vfs_mount) == 0);
@ -412,6 +419,7 @@ int main(void)
printf("Tests for FatFs over VFS - test results will be printed "
"in the format test_name:result\n");
test_format();
test_mount();
test_open();
test_rw();