nrf52840 DK, nRF Connect SDK 2.3.0 using vsCode, FAT Filesystem Sample Application
Working with the FAT_FS sample code, I am able to communicate with the SD card perfectly fine, as far as I can tell. The call to lsdir() functions as expected. However, when calling fs_open() to open a file to write to on an external SD card, it is returning error code -2 IF the filepath (mount point + filename) is longer than 14 characters. If the filepath is less than 14 characters then it will successfully write data. I thought it might be resolved by enabling CONFIG_FS_FATFS_LFN, however it did not work. See the code below for my example.
/* File operations */ int fs_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags) { struct fs_mount_t *mp; int rc = -EINVAL; if ((file_name == NULL) || (strlen(file_name) <= 1) || (file_name[0] != '/')) { LOG_ERR("invalid file name!!"); return -EINVAL; } if (zfp->mp != NULL) { return -EBUSY; } rc = fs_get_mnt_point(&mp, file_name, NULL); if (rc < 0) { LOG_ERR("mount point not found!!"); return rc; } if (((mp->flags & FS_MOUNT_FLAG_READ_ONLY) != 0) && (flags & FS_O_CREATE || flags & FS_O_WRITE)) { return -EROFS; } CHECKIF(mp->fs->open == NULL) { return -ENOTSUP; } zfp->mp = mp; rc = mp->fs->open(zfp, file_name, flags); if (rc < 0) { LOG_ERR("file open error (%d)", rc); zfp->mp = NULL; return rc; } /* Copy flags to zfp for use with other fs_ API calls */ zfp->flags = flags; return rc; }
main.c
#include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/storage/disk_access.h> #include <zephyr/logging/log.h> #include <zephyr/fs/fs.h> #include <ff.h> static FATFS fat_fs; /* mounting info */ static struct fs_mount_t mp = { .type = FS_FATFS, .fs_data = &fat_fs, }; static const char *disk_mount_pt = "/SD:"; void main(void) { mp.mnt_point = disk_mount_pt; int res = fs_mount(&mp); if (res == FR_OK) { printk("Disk mounted.\n"); lsdir(disk_mount_pt); } else { printk("Error mounting disk.\n"); } char datatest[] = "1,2,3,4,5,6\n"; size_t datatest_size = strlen(datatest); struct fs_file_t dfile; size_t written_size = 0; fs_file_t_init(&dfile); // This is where the code fails. res = fs_open(&dfile, "/SD:/DKlog.txt", FS_O_RDWR | FS_O_APPEND); if(res < 0) return false; written_size = fs_write(&dfile, datatest, datatest_size); res = fs_close(&dfile); while (1) { ret = toggle_leds(); k_msleep(SLEEP_TIME_MS); } }
Relevant prj.conf settings
CONFIG_DISK_ACCESS=y CONFIG_FILE_SYSTEM=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_DISK_DRIVER_SDMMC=y CONFIG_FS_FATFS_LFN=y CONFIG_MAIN_STACK_SIZE=4096 CONFIG_SPI=y