From d41832f83085b196bbcc283b3c01f327ead83b59 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 28 Oct 2022 14:51:22 +0000 Subject: [PATCH] modules/fatfs: Move FATFS Zephyr specific code and cmake The code moves Zephyr specific code and CMakeLists.txt under modules/fatfs/. The commit also adds zephyr_fatfs_config.h header file, that is now used to override FF_ options of ffconf.h file within fatfs repository. Signed-off-by: Dominik Ermel --- modules/fatfs/CMakeLists.txt | 26 +++++++ modules/fatfs/Kconfig | 8 ++ modules/fatfs/zephyr_fatfs_config.h | 100 ++++++++++++++++++++++++ modules/fatfs/zfs_diskio.c | 117 ++++++++++++++++++++++++++++ 4 files changed, 251 insertions(+) create mode 100644 modules/fatfs/CMakeLists.txt create mode 100644 modules/fatfs/Kconfig create mode 100644 modules/fatfs/zephyr_fatfs_config.h create mode 100644 modules/fatfs/zfs_diskio.c diff --git a/modules/fatfs/CMakeLists.txt b/modules/fatfs/CMakeLists.txt new file mode 100644 index 00000000000..97371b1fb44 --- /dev/null +++ b/modules/fatfs/CMakeLists.txt @@ -0,0 +1,26 @@ +if(CONFIG_FAT_FILESYSTEM_ELM) + add_library(ELMFAT INTERFACE) + + target_include_directories(ELMFAT INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR} + ${ZEPHYR_FATFS_MODULE_DIR}/include + ) + + target_compile_definitions(ELMFAT INTERFACE + ZEPHYR_CONFIG_OVERRIDE=zephyr_fatfs_config.h + ) + + zephyr_library() + zephyr_library_sources( + ${ZEPHYR_FATFS_MODULE_DIR}/ff.c + zfs_diskio.c + ) + + zephyr_library_sources_ifdef(CONFIG_FS_FATFS_LFN + ${ZEPHYR_FATFS_MODULE_DIR}/option/ffunicode.c + ${ZEPHYR_FATFS_MODULE_DIR}/option/ffsystem.c + ) + + zephyr_library_link_libraries(ELMFAT) + target_link_libraries(ELMFAT INTERFACE zephyr_interface) +endif() diff --git a/modules/fatfs/Kconfig b/modules/fatfs/Kconfig new file mode 100644 index 00000000000..f21ecf1acf6 --- /dev/null +++ b/modules/fatfs/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2022 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config ZEPHYR_FATFSFS_MODULE + bool + +# Configuration of ELM FAT is found in subsys/fs/Kconfig.fatfs for historic +# reasons. diff --git a/modules/fatfs/zephyr_fatfs_config.h b/modules/fatfs/zephyr_fatfs_config.h new file mode 100644 index 00000000000..fb633d24851 --- /dev/null +++ b/modules/fatfs/zephyr_fatfs_config.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#if FFCONF_DEF != 86631 +#error "Configuration version mismatch" +#endif + +/* + * Overrides of FF_ options from ffconf.h + */ +#if defined(CONFIG_FS_FATFS_READ_ONLY) +#undef FF_FS_READONLY +#define FF_FS_READONLY CONFIG_FS_FATFS_READ_ONLY +#endif /* defined(CONFIG_FS_FATFS_READ_ONLY) */ + +#if defined(CONFIG_FS_FATFS_MKFS) +#undef FF_USE_MKFS +#define FF_USE_MKFS CONFIG_FS_FATFS_MKFS +#else +/* Note that by default the ffconf.h disables MKFS */ +#undef FF_USE_MKFS +#define FF_USE_MKFS 1 +#endif /* defined(CONFIG_FS_FATFS_MKFS) */ + +#if defined(CONFIG_FS_FATFS_CODEPAGE) +#undef FF_CODE_PAGE +#define FF_CODE_PAGE CONFIG_FS_FATFS_CODEPAGE +#else +/* Note that default value, in ffconf.h, for FF_CODE_PAGE is 932 */ +#undef FF_CODE_PAGE +#define FF_CODE_PAGE 437 +#endif /* defined(CONFIG_FS_FATFS_CODEPAGE) */ + +#if defined(CONFIG_FS_FATFS_LFN) +#undef FF_USE_LFN +#if CONFIG_FS_FATFS_LFN_MODE_BSS +#define FF_USE_LFN 1 +#elif CONFIG_FS_FATFS_LFN_MODE_STACK +#define FF_USE_LFN 2 +#elif CONFIG_FS_FATFS_LFN_MODE_HEAP +#define FF_USE_LFN 3 +#else +#error Invalid LFN buffer location +#endif +#endif /* defined(CONFIG_FS_FATFS_LFN) */ + +#if defined(CONFIG_FS_FATFS_MAX_LFN) +#undef FF_MAX_LFN +#define FF_MAX_LFN CONFIG_FS_FATFS_MAX_LFN +#endif /* defined(CONFIG_FS_FATFS_MAX_LFN) */ + +#if defined(CONFIG_FS_FATFS_MAX_SS) +#undef FF_MAX_SS +#define FF_MAX_SS CONFIG_FS_FATFS_MAX_SS +#endif /* defined(CONFIG_FS_FATFS_MAX_SS) */ + +#if defined(CONFIG_FS_FATFS_EXFAT) +#undef FF_FS_EXFAT +#define FF_FS_EXFAT CONFIG_FS_FATFS_EXFAT +#endif /* defined(CONFIG_FS_FATFS_EXFAT) */ + +/* + * These options are override from default values, but have no Kconfig + * options. + */ +#undef FF_FS_TINY +#define FF_FS_TINY 1 + +#undef FF_FS_NORTC +#define FF_FS_NORTC 1 + +/* Zephyr uses FF_VOLUME_STRS */ +#undef FF_STR_VOLUME_ID +#define FF_STR_VOLUME_ID 1 + +/* By default FF_STR_VOLUME_ID in ffconf.h is 0, which means that + * FF_VOLUME_STRS is not used. Zephyr uses FF_VOLUME_STRS, which + * by default holds 8 possible strings representing mount points, + * and FF_VOLUMES needs to reflect that, which means that dolt + * value of 1 is overridden here with 8. + */ +#undef FF_VOLUMES +#define FF_VOLUMES 8 + +/* + * Options provided below have been added to ELM FAT source code to + * support Zephyr specific features, and are not part of ffconf.h. + */ +/* + * The FS_FATFS_WINDOW_ALIGNMENT is used to align win buffer of FATFS structure + * to allow more optimal use with MCUs that require specific bufer alignment + * for DMA to work. + */ +#if defined(CONFIG_FS_FATFS_WINDOW_ALIGNMENT) +#define FS_FATFS_WINDOW_ALIGNMENT CONFIG_FS_FATFS_WINDOW_ALIGNMENT +#else +#define FS_FATFS_WINDOW_ALIGNMENT 1 +#endif /* defined(CONFIG_FS_FATFS_WINDOW_ALIGNMENT) */ diff --git a/modules/fatfs/zfs_diskio.c b/modules/fatfs/zfs_diskio.c new file mode 100644 index 00000000000..ab9c5468c3c --- /dev/null +++ b/modules/fatfs/zfs_diskio.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018-2021 Zephyr contributors + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* The file is based on template file by (C)ChaN, 2019, as + * available from FAT FS module source: + * https://github.com/zephyrproject-rtos/fatfs/blob/master/diskio.c + * and has been previously avaialble from directory for that module + * under name zfs_diskio.c. + */ +#include +#include /* FatFs lower layer API */ +#include + +static const char * const pdrv_str[] = {FF_VOLUME_STRS}; + +/* Get Drive Status */ +DSTATUS disk_status(BYTE pdrv) +{ + __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + + if (disk_access_status(pdrv_str[pdrv]) != 0) { + return STA_NOINIT; + } else { + return RES_OK; + } +} + +/* Initialize a Drive */ +DSTATUS disk_initialize(BYTE pdrv) +{ + __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + + if (disk_access_init(pdrv_str[pdrv]) != 0) { + return STA_NOINIT; + } else { + return RES_OK; + } +} + +/* Read Sector(s) */ +DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count) +{ + __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + + if (disk_access_read(pdrv_str[pdrv], buff, sector, count) != 0) { + return RES_ERROR; + } else { + return RES_OK; + } + +} + +/* Write Sector(s) */ +DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count) +{ + __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + + if (disk_access_write(pdrv_str[pdrv], buff, sector, count) != 0) { + return RES_ERROR; + } else { + return RES_OK; + } +} + +/* Miscellaneous Functions */ +DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) +{ + int ret = RES_OK; + uint32_t sector_size = 0; + + __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + + switch (cmd) { + case CTRL_SYNC: + if (disk_access_ioctl(pdrv_str[pdrv], + DISK_IOCTL_CTRL_SYNC, buff) != 0) { + ret = RES_ERROR; + } + break; + + case GET_SECTOR_COUNT: + if (disk_access_ioctl(pdrv_str[pdrv], + DISK_IOCTL_GET_SECTOR_COUNT, buff) != 0) { + ret = RES_ERROR; + } + break; + + case GET_SECTOR_SIZE: + /* Zephyr's DISK_IOCTL_GET_SECTOR_SIZE returns sector size as a + * 32-bit number while FatFS's GET_SECTOR_SIZE is supposed to + * return a 16-bit number. + */ + if ((disk_access_ioctl(pdrv_str[pdrv], + DISK_IOCTL_GET_SECTOR_SIZE, §or_size) == 0) && + (sector_size == (uint16_t)sector_size)) { + *(uint16_t *)buff = (uint16_t)sector_size; + } else { + ret = RES_ERROR; + } + break; + + case GET_BLOCK_SIZE: + if (disk_access_ioctl(pdrv_str[pdrv], + DISK_IOCTL_GET_ERASE_BLOCK_SZ, buff) != 0) { + ret = RES_ERROR; + } + break; + + default: + ret = RES_PARERR; + break; + } + return ret; +}