文章目录
一、简介
思澈芯片配置使用TF卡
需求:SD卡、思澈开发板
相关示例文档:
二、说明
黄山派 :支持采用SPI接口的TF卡,板载Micro SD卡插槽
从左往右引脚号是9~1

接口


三、示例使用
首先通过示例现象来熟悉相关设备使用。
1、读取SD卡ID
相关例程 :SPI 读取SD卡ID
源码路径:example\rt_device\spi\card
使用说明:直接编译下载即可
现象展示:下载后如果SD卡检测成功,会返回SD卡id


2、TF卡文件系统示例
相关例程 :SPI TF卡文件系统示例
源码路径:example\rt_device\spi_tf
使用说明:直接编译下载即可
现象展示 :下载成功后检测到SD卡,会自动挂载文件系统,显示挂载成功后可以通过FINSH命令进行使用。


接下来还可以使用定义的FINSH指令来进行测试

3、其他示例
eMMC/SD卡示例:源码路径:example/rt_device/emmc。类似spi_tf例程
MP3_player:源码路径:example/multimedia/audio/mp3_sd_player。可以读取SD卡中音频并播放。
本章着重TF卡的使用,暂时不涉及显示,如果对显示感兴趣,可以尝试下面的例程。
LVGL_V8_examples:源码路径:example\multimedia\lvgl\lvgl_v8_examples。可以读取SD卡图片并播放,该工程是一个多项目工程,需要一定的配置才能显示现象。
LVGL_V8_examples源码路径:example\multimedia\lvgl\lvgl_v9_examples。同V8项目示例。
四、从零配置
经过前面几个示例项目的使用,接下来我们看看如何开始配置一个项目工程。
1、项目配置
首先准备一个新的项目工程,这里使用
Hello_world例程打开
menuconfig并进行配置需要配置:
开启SPI1总线对应
CONFIG_BSP_USING_SPI1


将sd\tf设备挂载在spi总线上
对应
CONFIG_RT_USING_SPI_MSD


配置文件路径
对应
CONFIG_RT_USING_DFS_ELMFAT


2、代码说明
这些代码就是文件系统的注册与挂载
参考文档:文件系统
头文件&宏定义
c
#include "dfs_file.h"
#include "spi_msd.h"
#define FS_ROOT "root"
#define FS_ROOT_PATH "/" //统一根目录路径为 '/'
#define FS_ROOT_OFFSET 0X00000000 //起始地址
#define FS_ROOT_LEN 500*1024*1024 //500M
#define FS_BLOCK_SIZE 0x200
注册文件系统
c
//文件系统注册函数,需要将存储设备注册为块设备才能挂载到文件系统上。
struct rt_device *fal_mtd_msd_device_create(char *name, long offset, long len)
{
rt_device_t msd = rt_device_find("sd0");
if (msd == NULL)
{
rt_kprintf("Error: the flash device name (sd0) is not found.\n");
return NULL;
}
struct msd_device *msd_dev = (struct msd_device *)msd->user_data;
struct msd_device *msd_file_dev = (struct msd_device *)rt_malloc(sizeof(struct msd_device));
if (msd_file_dev)
{
msd_file_dev->parent.type = RT_Device_Class_MTD;
#ifdef RT_USING_DEVICE_OPS
msd_file_dev->parent.ops = msd_dev->parent.ops;
#else
msd_file_dev->parent.init = msd_dev->parent.init;
msd_file_dev->parent.open = msd_dev->parent.open;
msd_file_dev->parent.close = msd_dev->parent.close;
msd_file_dev->parent.read = msd_dev->parent.read;
msd_file_dev->parent.write = msd_dev->parent.write;
msd_file_dev->parent.control = msd_dev->parent.control;
#endif
msd_file_dev->offset = offset;
msd_file_dev->spi_device = msd_dev->spi_device;
msd_file_dev->geometry.bytes_per_sector = FS_BLOCK_SIZE;
msd_file_dev->geometry.block_size = FS_BLOCK_SIZE;
msd_file_dev->geometry.sector_count = len;
rt_device_register(&msd_file_dev->parent, name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
rt_kprintf("fal_mtd_msd_device_create dev:sd0 part:%s offset:0x%x, size:0x%x\n", name, msd_file_dev->offset, msd_file_dev->geometry.sector_count);
return RT_DEVICE(&msd_file_dev->parent);;
}
return NULL;
}
初始化并挂载
c
int mnt_init(void)
{
uint16_t time_out = 100;
while (time_out --)
{
rt_thread_mdelay(30);
if (rt_device_find("sd0"))
break;
}
/* 将'/' 注册为块设备,并挂载 */
fal_mtd_msd_device_create(FS_ROOT, FS_ROOT_OFFSET >> 9, FS_ROOT_LEN >> 9);
/* 挂载 FS_ROOT,挂载路径 FS_ROOT_PATH,挂载类型 'elm' */
if (dfs_mount(FS_ROOT, FS_ROOT_PATH, "elm", 0, 0) == 0) // fs exist
{
rt_kprintf("mount fs on flash to root success\n");
}
else
{
// auto mkfs, remove it if you want to mkfs manual
rt_kprintf("mount fs on flash to root fail\n");
if (dfs_mkfs("elm", FS_ROOT) == 0)//Format file system
{
rt_kprintf("make elm fs on flash sucess, mount again\n");
if (dfs_mount(FS_ROOT, "/", "elm", 0, 0) == 0)
rt_kprintf("mount fs on flash success\n");
else
{
rt_kprintf("mount to fs on flash fail\n");
return RT_ERROR;
}
}
else
rt_kprintf("dfs_mkfs elm flash fail\n");
}
extern int mkdir(const char *path, mode_t mode);
return RT_EOK;
}
INIT_ENV_EXPORT(mnt_init); //编译时自动调用mnt_init函数,不需要在main函数中再次调用
完整代码
c
#include "rtthread.h"
#include "bf0_hal.h"
#include "drv_io.h"
#include "stdio.h"
#include "string.h"
#include "dfs_file.h"
#include "spi_msd.h"
#define FS_ROOT "root"
#define FS_ROOT_PATH "/"
#define FS_ROOT_OFFSET 0X00000000
#define FS_ROOT_LEN 500*1024*1024 //500M
#define FS_BLOCK_SIZE 0x200
struct rt_device *fal_mtd_msd_device_create(char *name, long offset, long len)
{
rt_device_t msd = rt_device_find("sd0");
if (msd == NULL)
{
rt_kprintf("Error: the flash device name (sd0) is not found.\n");
return NULL;
}
struct msd_device *msd_dev = (struct msd_device *)msd->user_data;
struct msd_device *msd_file_dev = (struct msd_device *)rt_malloc(sizeof(struct msd_device));
if (msd_file_dev)
{
msd_file_dev->parent.type = RT_Device_Class_MTD;
#ifdef RT_USING_DEVICE_OPS
msd_file_dev->parent.ops = msd_dev->parent.ops;
#else
msd_file_dev->parent.init = msd_dev->parent.init;
msd_file_dev->parent.open = msd_dev->parent.open;
msd_file_dev->parent.close = msd_dev->parent.close;
msd_file_dev->parent.read = msd_dev->parent.read;
msd_file_dev->parent.write = msd_dev->parent.write;
msd_file_dev->parent.control = msd_dev->parent.control;
#endif
msd_file_dev->offset = offset;
msd_file_dev->spi_device = msd_dev->spi_device;
msd_file_dev->geometry.bytes_per_sector = FS_BLOCK_SIZE;
msd_file_dev->geometry.block_size = FS_BLOCK_SIZE;
msd_file_dev->geometry.sector_count = len;
rt_device_register(&msd_file_dev->parent, name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
rt_kprintf("fal_mtd_msd_device_create dev:sd0 part:%s offset:0x%x, size:0x%x\n", name, msd_file_dev->offset, msd_file_dev->geometry.sector_count);
return RT_DEVICE(&msd_file_dev->parent);;
}
return NULL;
}
int mnt_init(void)
{
uint16_t time_out = 100;
while (time_out --)
{
rt_thread_mdelay(30);
if (rt_device_find("sd0"))
break;
}
fal_mtd_msd_device_create(FS_ROOT, FS_ROOT_OFFSET >> 9, FS_ROOT_LEN >> 9);
if (dfs_mount(FS_ROOT, FS_ROOT_PATH, "elm", 0, 0) == 0) // fs exist
{
rt_kprintf("mount fs on flash to root success\n");
}
else
{
// auto mkfs, remove it if you want to mkfs manual
rt_kprintf("mount fs on flash to root fail\n");
if (dfs_mkfs("elm", FS_ROOT) == 0)//Format file system
{
rt_kprintf("make elm fs on flash sucess, mount again\n");
if (dfs_mount(FS_ROOT, "/", "elm", 0, 0) == 0)
rt_kprintf("mount fs on flash success\n");
else
{
rt_kprintf("mount to fs on flash fail\n");
return RT_ERROR;
}
}
else
rt_kprintf("dfs_mkfs elm flash fail\n");
}
extern int mkdir(const char *path, mode_t mode);
return RT_EOK;
}
INIT_ENV_EXPORT(mnt_init);
/**
* @brief Main program
* @param None
* @retval 0 if success, otherwise failure number
*/
int main(void)
{
/* Output a message on console using printf function */
rt_kprintf("Hello world!\n");
/* Infinite loop */
while (1)
{
// Delay for 1000 ms to yield CPU time to other threads
rt_thread_mdelay(1000);
}
return 0;
}
3、项目编译/下载/测试
编译通过,下载查看现象
下载后log自动显示SD卡信息,同时出现
mount fs on flash root success说明文件系统挂载成功

输入创建文件夹指令mkdir可以看到成功创建文件夹
