STM32 Zephyr SD Card Support
I couldn't find much info on adding SD card support to an existing zephyr application. Sharing my setup here.
Device tree and configuration changes
Added this to the board-name.dts
file
&sdmmc1 {
compatible = "st,stm32-sdmmc";
pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9
&sdmmc1_d2_pc10 &sdmmc1_d3_pc11
&sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>;
pinctrl-names = "default";
pwr-gpios = <&gpiod 15 GPIO_ACTIVE_HIGH>; // required
status = "okay";
};
Added this to the board-name_defconfig
file
#enable disk
CONFIG_DISK_ACCESS=y
CONFIG_DISK_DRIVER_SDMMC=y
CONFIG_SDMMC_STM32=y
CONFIG_FAT_FILESYSTEM_ELM=y
Integrating sample code into your application to read directory contents
#ifdef CONFIG_FAT_FILESYSTEM_ELM
#include <ff.h>
#include <string.h>
/* FatFs work area */
FATFS fatfs_fs;
/* mounting info */
static struct fs_mount_t fat_fs_mnt = {
.type = FS_FATFS,
.fs_data = &fatfs_fs,
.mnt_point = "/SD:"
};
#endif
static int lsdir(const char *path)
{
int res;
struct fs_dir_t dirp;
static struct fs_dirent entry;
fs_dir_t_init(&dirp);
/* Verify fs_opendir() */
res = fs_opendir(&dirp, path);
if (res) {
LOG_WRN("Error opening dir %s [%d]", path, res);
return res;
}
LOG_INF("Listing dir %s ...", path);
for (;;) {
/* Verify fs_readdir() */
res = fs_readdir(&dirp, &entry);
/* entry.name[0] == 0 means end-of-dir */
if (res || entry.name[0] == 0) {
break;
}
if (entry.type == FS_DIR_ENTRY_DIR) {
if(strchr(entry.name, '~') != NULL){
LOG_INF("[DIR ] %s", entry.name);
}
} else {
if(entry.name[0] != '_'){
LOG_INF("[FILE] %s (size = %zu)",
entry.name, entry.size);
}
}
}
/* Verify fs_closedir() */
fs_closedir(&dirp);
return res;
}
static int fatfs_mount()
{
/* raw disk i/o */
do {
static const char *disk_pdrv = "SD";
uint64_t memory_size_mb;
uint32_t block_count;
uint32_t block_size;
if (disk_access_init(disk_pdrv) != 0) {
LOG_ERR("Storage init ERROR!");
break;
}
if (disk_access_ioctl(disk_pdrv,
DISK_IOCTL_GET_SECTOR_COUNT, &block_count)) {
LOG_ERR("Unable to get sector count");
break;
}
LOG_INF("Block count %u", block_count);
if (disk_access_ioctl(disk_pdrv,
DISK_IOCTL_GET_SECTOR_SIZE, &block_size)) {
LOG_ERR("Unable to get sector size");
break;
}
LOG_INF("Sector size %u", block_size);
memory_size_mb = (uint64_t)block_count * block_size;
LOG_INF("Memory Size(MB) %u", (uint32_t)(memory_size_mb >> 20));
} while (0);
int res = fs_mount(&fat_fs_mnt);
if (res == FR_OK) {
LOG_INF("SD Card mounted.");
lsdir(fat_fs_mnt.mnt_point);
} else {
LOG_WRN("Error mounting disk.\n");
}
return 0;
}
Results:
After zephyr boots, the application is able to connect to sd card, mount fat file system and read its contexts.
uart:~$
*** Booting Zephyr OS build zephyr-v3.2.0-4019-g16d723ee1be9 ***
[00:00:02.065,000] <inf> file_system: Begin File System
[00:00:02.253,000] <inf> file_system: Block count 62333952
[00:00:02.261,000] <inf> file_system: Sector size 512
[00:00:02.269,000] <inf> file_system: Memory Size(MB) 30436
[00:00:02.279,000] <inf> file_system: SD Card mounted.
[00:00:02.286,000] <inf> file_system: Listing dir /SD: ...
[00:00:02.295,000] <inf> file_system: [DIR ] SPOTLI~1
[00:00:02.303,000] <inf> file_system: [FILE] NOTE.PDF (size = 315197)
[00:00:02.312,000] <inf> file_system: [FILE] AA2.TXT (size = 2704195)
[00:00:02.321,000] <inf> file_system: [FILE] A.TXT (size = 6)
Zephyr page on stm32 sd card link