Hi, we have recently started developing with the nRF5340DK. We encountered several issues while configuring a FATFS on the external flash (mx25r64).
1. The sample code located here [zephyrproject-fs_sample](github.com/.../fs_sample) fails to build out of the box.
nRF52840 fails with the warning:
No SOURCES given to Zephyr library: drivers__disk
nRF5340 fails with the error:
C:/ncs/v2.9.0/zephyr/drivers/disk/flashdisk.c:533:1:
error: return type defaults to 'int' [-Werror=implicit-int] 533
PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_CACHE)
The solution for this is to add the following config options to the prj.conf:
CONFIG_FLASH=ys
CONFIG_FLASH_MAP=y
It will likely affect some of the other board samples, but I have not had time to look into it more. It would be great if this issue could be fixed upstream so it will work out of the box for others.
2. As the nRF5340 is a multicore SoC, it defaults to using sysbuild, which requires [partition manager](docs.nordicsemi.com/.../partition_manager.html).
After creating pm_static.yml and overlay files as follows:
mx25r64:
affiliation:
- disk
region: external_flash
size: 0x800000
address: 0x000000
end_address: 0x7FFFFF
extra_params: {
disk_name: "SD",
disk_cache_size: 4096,
disk_sector_size: 4096,
disk_read_only: 0
} / {
chosen {
nordic,pm-ext-flash = &mx25r64;
};
};
Attempting to compile results in the following warning:
warning: DISK_DRIVER_FLASH (defined at drivers/disk/Kconfig.flash:4)
was assigned the value 'y' but got the value 'n'.
Check these unsatisfied dependencies: DT_HAS_ZEPHYR_FLASH_DISK_ENABLED (=n).
and/or look up DISK_DRIVER_FLASH in the menuconfig/guiconfig interface.
The Application Development Primer, Setting Configuration Values, and Kconfig
Tips and Best Practices sections of the manual might be helpful too.
This seems to imply the flash disk driver is not being loaded, as this is usually done by:
`msc_disk0 { compatible = "zephyr,flash-disk" }`
Adding it as follows does seem to resolve this issue:
/ {
chosen {
nordic,pm-ext-flash = &mx25r64;
};
msc_disk0 {
status="okay";
compatible = "zephyr,flash-disk";
// What is the correct way to refer to a
// Partition Manager partition here?
partition = <&mx25r64>;
disk-name = "SD";
cache-size = <4096>;
};
};
Setting `DT_HAS_ZEPHYR_FLASH_DISK_ENABLED` does not seem like a good idea, so is this the best way to resolve this? If correct, how can I reference a partition manager partition from the device tree, as the docs are unclear? I feel `partition = <&mx25r64>;` likely is not the correct way to do this. However, adding the partition in the device tree also seems wrong, as the device tree ignores it since the partition manager is enabled.
&mx25r64 {
partitions {
compatible = "fixed-partitions";
external_partition: partition@0 {
reg = <0x00000000 0x00020000>;
};
};
};
So, what is the best way to configure this?
3. While the sample code now appears to run correctly, enabling multithreading resulted in random hard faults. After much debugging, I traced this back to FatFs reading a 4096-byte sector from the mx25r64 into the 512-byte default sector buffer in FatFS. This overruns the stack, causing other threads, such as the logging thread, to hard fault and access invalid memory addresses.
I would have assumed that setting `cache-size = <4096>;` in the device tree or `disk_sector_size: 4096` in the partition manager would correctly update this value in the FatFs config. However, this does not seem to be the case, and it seems necessary to set `CONFIG_FS_FATFS_MAX_SS=4096` in the prj.conf.
If this is the intended behavior, this should already be set for the nRF board examples, including the mx25r64. It would also be great to see this somewhere in the docs instead of digging through the kconfig tool to find it. It is also relatively simple to make the sample code throw an error if the sector size is not set correctly.
if (disk_access_ioctl(disk_pdrv,
DISK_IOCTL_GET_SECTOR_SIZE, &block_size)) {
LOG_ERR("Unable to get sector size");
break;
} else if (block_size > sizeof(fat_fs.win)) {
LOG_ERR("Sector size %u is larger than FF_MAX_SS %u\n\
set CONFIG_FS_FATFS_MAX_SS=%u\n",
block_size, sizeof(fat_fs.win), block_size);
break;
} else {
printk("Sector size %u\n", block_size);
}
Ideally, the device tree and partition manager settings should set the FatFs settings correctly, as I'm not sure what else these values would be used for.