Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fs: enable fstab devicetree integration for fatfs #84147

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions dts/bindings/fs/zephyr,fstab,fatfs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (C) 2025 Endress+Hauser AG
# SPDX-License-Identifier: Apache-2.0

description: |
Description of pre-defined fatfs file systems.

compatible: "zephyr,fstab,fatfs"

include: zephyr,fstab-common.yaml
6 changes: 6 additions & 0 deletions dts/bindings/fs/zephyr,fstab,littlefs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ include: "zephyr,fstab-common.yaml"
properties:
# num-files and num-dirs are not filesystem-specific.

partition:
type: phandle
required: true
description: |
A reference to the file system's partition.

read-size:
type: int
required: true
Expand Down
6 changes: 0 additions & 6 deletions dts/bindings/fs/zephyr,fstab-common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ properties:
description: |
The absolute path used as the file system mount point.

partition:
type: phandle
required: true
description: |
A reference to the file system's partition.

automount:
type: boolean
description: |
Expand Down
9 changes: 9 additions & 0 deletions samples/subsys/fs/fatfs_fstab/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025 Endress+Hauser AG
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(fatfs_fstab_sample)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
36 changes: 36 additions & 0 deletions samples/subsys/fs/fatfs_fstab/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.. zephyr:code-sample:: fatfs-fstab
:name: Fatfs filesystem fstab
:relevant-api: file_system_api

Define fatfs filesystems in the devicetree.

Overview
***********

This sample shows how to define a fatfs fstab entry in the devicetree.
This scenario uses a fatfs on a RAM disk. The sample is run on the
``native_sim`` board.

Building and running
********************

To run this sample, build it for the ``native_sim`` board
and afterwards run the generated executable file within the build folder.

The RAM disk sample for the ``native_sim`` board can be built as follows:

.. zephyr-app-commands::
:zephyr-app: samples/subsys/fs/fatfs_fstab
:host-os: unix
:board: native_sim
:gen-args: -DDTC_OVERLAY_FILE=fatfs_fstab.overlay
:goals: build
:compact:

Sample Output
=============

When the sample runs successfully you should see following message on the screen:
.. code-block:: console

I: Filesystem access successful
24 changes: 24 additions & 0 deletions samples/subsys/fs/fatfs_fstab/fatfs_fstab.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2025 Endress+Hauser AG
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
fstab {
compatible = "zephyr,fstab";
ffs1: ffs1 {
compatible = "zephyr,fstab,fatfs";
automount;
disk-access;
mount-point = "/RAM";
};
};

ramdisk0 {
compatible = "zephyr,ram-disk";
disk-name = "RAM";
sector-size = <512>;
sector-count = <128>;
};
};
9 changes: 9 additions & 0 deletions samples/subsys/fs/fatfs_fstab/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CONFIG_DISK_ACCESS=y
CONFIG_DISK_DRIVERS=y

CONFIG_LOG=y
CONFIG_LOG_MODE_MINIMAL=y

CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_MKFS=y
CONFIG_FAT_FILESYSTEM_ELM=y
14 changes: 14 additions & 0 deletions samples/subsys/fs/fatfs_fstab/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
sample:
name: fatfs fstab sample
tests:
sample.filesystem.fat_fs.fstab:
platform_allow:
- native_sim
extra_args:
- EXTRA_DTC_OVERLAY_FILE="fatfs_fstab.overlay"
tags: filesystem
harness: console
harness_config:
type: one_line
regex:
- "I: Filesystem access successful"
41 changes: 41 additions & 0 deletions samples/subsys/fs/fatfs_fstab/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2025 Endress+Hauser AG
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <ff.h>
#include <zephyr/device.h>
#include <zephyr/fs/fs.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/storage/disk_access.h>

LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

int main(void)
{
struct fs_file_t file;
int rc;
static const char data[] = "Hello";

fs_file_t_init(&file);
rc = fs_open(&file, "/RAM:/hello.txt", FS_O_CREATE | FS_O_WRITE);
if (rc != 0) {
LOG_ERR("Accessing filesystem failed");
return rc;
}
rc = fs_write(&file, data, strlen(data));
if (rc != strlen(data)) {
LOG_ERR("Writing filesystem failed");
return rc;
}
rc = fs_close(&file);
if (rc != 0) {
LOG_ERR("Closing file failed");
return rc;
}

LOG_INF("Filesystem access successful");
return 0;
}
46 changes: 45 additions & 1 deletion subsys/fs/fat_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,54 @@ static const struct fs_file_system_t fatfs_fs = {
#endif
};

#define DT_DRV_COMPAT zephyr_fstab_fatfs

#define DEFINE_FS(inst) \
BUILD_ASSERT(DT_INST_PROP(inst, disk_access), "FATFS needs disk-access"); \
BUILD_ASSERT(!DT_INST_PROP(inst, read_only), \
"READ_ONLY not supported for individual instances see FS_FATFS_READ_ONLY"); \
BUILD_ASSERT(!DT_INST_PROP(inst, no_format), \
"NO_FORMAT not supported for individual instanzes FS_FATFS_MKFS"); \
FATFS fs_data_##inst; \
struct fs_mount_t FS_FSTAB_ENTRY(DT_DRV_INST(inst)) = { \
.type = FS_FATFS, \
.mnt_point = DT_INST_PROP(inst, mount_point) ":", \
.fs_data = &fs_data_##inst, \
.storage_dev = NULL, \
.flags = FSTAB_ENTRY_DT_MOUNT_FLAGS(DT_DRV_INST(inst)), \
};

DT_INST_FOREACH_STATUS_OKAY(DEFINE_FS);

#define REFERENCE_MOUNT(inst) (&FS_FSTAB_ENTRY(DT_DRV_INST(inst)))

static int fatfs_init(void)
{
int rc = fs_register(FS_FATFS, &fatfs_fs);

if (rc == 0) {
static struct fs_mount_t *partitions[] = {
DT_INST_FOREACH_STATUS_OKAY(REFERENCE_MOUNT)};
int ret = 0;

for (size_t i = 0; i < ARRAY_SIZE(partitions); i++) {
struct fs_mount_t *mpi = partitions[i];

if ((mpi->flags & FS_MOUNT_FLAG_AUTOMOUNT) != 0) {
ret = fs_mount(mpi);
if (ret < 0) {
LOG_ERR("Error mounting filesystem: mount id %u at %s: %d",
(unsigned int)mpi->storage_dev, mpi->mnt_point,
ret);
} else {
LOG_DBG("FATFS Filesystem \"%s\" initialized",
mpi->mnt_point);
}
}
}
}

return fs_register(FS_FATFS, &fatfs_fs);
return rc;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be a little bit of problem, because failing to mount any fstab, for example due to damaged fat, will imply that registration of fs failed.

There is also needed a testcase for automount of fat, and this PR does not provide any.

Copy link
Contributor Author

@kica-z kica-z Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove the return value overwrite so that the return only indicates if the registration of the fs succeeded or not. For info regarding the specific filesystems we have the logs with the return code so i think that should suffice.

I will also provided a testcase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@de-nordic I adjusted the return value handling and also added a sample/test.

}

SYS_INIT(fatfs_init, POST_KERNEL, CONFIG_FILE_SYSTEM_INIT_PRIORITY);
Loading