黄山派 TF卡使用

文章目录

一、简介

思澈芯片配置使用TF卡

需求:SD卡、思澈开发板

相关示例文档:

EMMC/SD卡示例

SPI TF卡文件系统示例

SPI TF

MP3_player

LVGL_V8_examples

LVGL_V8_examples

二、说明

黄山派 :支持采用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项目示例。

四、从零配置

经过前面几个示例项目的使用,接下来我们看看如何开始配置一个项目工程。

同时你需要了解相关的前置知识,包括:FINSH/文件系统
FINSH
文件系统

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可以看到成功创建文件夹

相关推荐
玩具猴_wjh1 小时前
11.30 学习笔记
笔记·学习
一尘之中2 小时前
冰海通航的科技密码:葫芦岛港的破冰实践与智慧港口建设
人工智能·科技·ai写作
趣Python2 小时前
【看好恒生科技】低频量化周报(指数风险溢价比,配债完整数据集,可转债策略,上市公司礼品,交易总结)
科技
雷工笔记2 小时前
MES学习笔记之MES系统的作用和定位及与SCADA的关系
大数据·笔记·学习
c***93772 小时前
Spring Security 官网文档学习
java·学习·spring
韩曙亮2 小时前
【人工智能】AI 人工智能 技术 学习路径分析 ③ ( NLP 自然语言处理 )
人工智能·pytorch·学习·ai·自然语言处理·nlp·tensorflow
雷工笔记2 小时前
MES学习笔记之MES常见的类别
笔记·学习
丝斯20112 小时前
AI学习笔记整理(20)—— AI核心技术(深度学习4)
人工智能·笔记·学习
我的xiaodoujiao3 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 28--开源电商商城系统项目实战--封装注册页面
python·学习·测试工具·pytest