Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
文件系统
SD卡_TF卡
SDIO总线
RTThread平台使用DFS文件系统
1.00
发布于 2022-04-30 11:24:56 浏览:8044
订阅该版
[tocm] #基于RTThread的DFS文件系统组件使用笔记 简单介绍了一下DFS代码框架和如何在RTThread平台上使用DFS分布式文件系统。工作比较忙先把目前整理的发出来,希望对小伙伴们有帮助,也希望玩过的朋友一起讨论指正。等空闲下来再继续细化深入分析一下。甚至看看能不能挂载个网络文件系统玩玩。 - 环境用的RTThreadStudio - RTThread版本:标准版4.0.3 - 硬件平台:自己做的产品电路板,MCU用的STM32F407VET6 ##DFS分布式文件系统框架如下: ![DFS虚拟文件系统框架](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/filesystem/figures/fs-layer.png "DFS虚拟文件系统框架") ##主要特点: 1. 支持多种类型的存储设备。 2. 支持多种类型的文件系统,提供普通文件、设备文件、网络文件描述符的管理。 3. 提供统一的POSIX文件操作接口:read、write、poll/select等。 ##DFS虚拟文件系统文件目录如下: ![DFS虚拟文件系统目录.png](https://oss-club.rt-thread.org/uploads/20220430/af655c2754d61303b6c82af308df750b.png) ##关键文件简单介绍如下(详见具体的API手册): - **src文件夹:** dfs虚拟文件系统层相关代码 - **dfs_posix.c** 对上层的调用接口代码 - **int open(const char *file, int flags, ...)** 打开文件 - **int close(int fd)** 关闭文件 - **int read(int fd, void *buf, size_t len)** 读取文件 - **int write(int fd, const void *buf, size_t len)** 写入文件 - **off_t lseek(int fd, off_t offset, int whence)** 移动文件读写位置 - **int rename(const char *old_file, const char *new_file)** 重命名文件 - **int unlink(const char *pathname)** 删除文件 - **int stat(const char *file, struct stat *buf)** 读取文件信息 - **int fstat(int fildes, struct stat *buf)** 读取文件状态 - **int fsync(int fildes)** 把文件描述符对应文件的缓冲区数据,写入对应磁盘文件,清空缓存区 - **int fcntl(int fildes, int cmd, ...)** 文件的ioctl接口,针对dfs层只能读取和设置文件flags。对应具体文件系统,由具体文件系统的ioctl接口定义 - **int ioctl(int fildes, int cmd, ...)** 文件的ioctl接口,内部调用上面的fcntl,如此,对外只需调用ioctl即可 - **int ftruncate(int fd, off_t length)** 按照length长度截断文件 - **int statfs(const char *path, struct statfs *buf)** 读取文件系统信息,包括block大小,block总数,剩余block数,用于计算剩余空间 - **int mkdir(const char *path, mode_t mode)** 创建文件夹,目前mode内部并没有使用,无实际意义。可配置为0x777 - **int rmdir(const char *pathname)** 删除文件夹 - **DIR *opendir(const char *name)** 打开文件夹 - **struct dirent *readdir(DIR *d)** 读取文件夹,可打开一个文件夹后,连续调用此函数遍历读取文件夹内所有子文件夹和文件,dirent内的d_type表明文件类型,1为文件,2为文件夹 - **long telldir(DIR *d)** 读取目录流中的当前位置(尚未测试有何用途) - **void seekdir(DIR *d, off_t offset)** 设置目录流中的读写位置(尚未测试有何用途) - **void rewinddir(DIR *d)** 复位目录流中的读写位置(尚未测试有何用途) - **int closedir(DIR *d)** 关闭文件夹 - **int chdir(const char *path)** 更改当前目录 - **int access(const char *path, int amode)** 测试文件是否可以访问 - **char *getcwd(char *buf, size_t size)** 读取当前路径 - **dfs.c** dfs文件系统初始化,文件句柄列表管理等接口函数 - **int dfs_init(void)** 初始化dfs文件系统,如果使能devfs,则直接挂载。此接口程序默认被rtthread设置为组件前自动初始化,无需用户调用。需发生在挂载底层文件系统之前 - **void dfs_lock(void)** 尝试获取dfs的互斥量,如果已被占用,则挂起当前线程,等待其它线程让出dfs操作权 - **void dfs_unlock(void)** 释放dfs互斥量,让出dfs操作权 - **static int fd_alloc(struct dfs_fdtable *fdt, int startfd)** 如果已打开的文件句柄列表内有空余句柄,则直接返回。如果没有空余,则在打开文件的时候需要新开辟空间,扩充已打开的文件句柄列表(每次扩充4个)。如果已超过同时打开文件的数量上限,则不再开辟。***但这里没有直接返回错误,而是返回最大文件描述符。等待调用者做越界保护处理*** - **int fd_new(void)** 调用上面的fd_alloc函数,申请一个空文件描述符。如果越界(没有空闲设备描述符可用)则返回-1.否则返回+3的描述符.0,1,2的文件描述符用于承载终端设备文件描述符 - **struct dfs_fd *fd_get(int fd)** 通过文件描述符,在文件句柄列表内找出对应的文件句柄 - **void fd_put(struct dfs_fd *fd)** 如果文件句柄的ref_count减一后为0,则释放掉文件句柄。 - **int fd_is_open(const char *pathname)** 查找某文件是否已打开,0为打开,-1为未打开。 - **const char *dfs_subdir(const char *directory, const char *filename)** 在filename中去掉directory,返回相对子目录 - **char *dfs_normalize_path(const char *directory, const char *filename)** 返回标准格式的路径 - **struct dfs_fdtable *dfs_fdtable_get(void)** 返回文件句柄列表 - **int list_fd(void)** 打印当前文件句柄列表内,已打开的文件属性 - **dfs_fs.c** dfs层文件系统对底层具体文件系统的管理接口函数 - **int dfs_register(const struct dfs_filesystem_ops *ops)** 注册一个具体的文件系统(dev,elm等)。具体操作为在文件系统操作符数组中,找出空闲句柄,并添加为新注册的操作符 - **struct dfs_filesystem *dfs_filesystem_lookup(const char *path)** 根据路径名,在文件系统列表中查找对应的文件系统。路径名只要包含文件系统具体挂载点即可。比如给定一个文件的绝对路径名,即可找到它所在的文件系统 - **const char *dfs_filesystem_get_mounted_path(struct rt_device *device)** 根据设备ID,在文件系统列表中查找对应的文件系统,并返回对应文件系统的挂载点 - **int dfs_filesystem_get_partition(struct dfs_partition *part,uint8_t *buf,uint32_t pindex)** 在指定存储空间内读取分区表。一般分区表在存储设备的第一个扇区。 - **int dfs_mount(const char *device_name,const char *path,const char *filesystemtype,unsigned long rwflag,const void *data)** 根据设备名,把该设备挂载到指定路径。filesystemtype指定具体的文件系统类型,以使用具体的操作接口。rwflag为文件系统的读写属性,data为传的参数,是否有实际意义要看具体的文件系统操作接口。常用的elm和dev文件系统都无实际意义,直接给0即可。该函数需要等注册完具体的存储设备和dfs文件系统并在dfs文件系统内注册了具体的文件系统后,由用户调用,把具体的存储设备挂载到dfs的指定挂载点。并指定以哪种类型的文件系统操作接口处理此设备。在此之前无需open对应的存储设备,此函数内部会先打开存储设备再挂载 - **int dfs_unmount(const char *specialfile)** 取消挂载,在文件系统列表中删除指定文件系统,关闭存储设备。specialfile只需包含文件系统挂载路径即可 - **int dfs_mkfs(const char *fs_name, const char *device_name)** 根据fs_name指定的具体文件系统类型,把device_name指定的实际存储设备进行格式化,构建文件系统 - **int dfs_statfs(const char *path, struct statfs *buffer)** 读取指定文件系统的信息,包括块大小,总块数以及剩余块数,可以用于查看设备剩余空间 - **void mkfs(const char *fs_name, const char *device_name)** finsh函数命令的mkfs接口。使能了MSH后,此函数未被使用 - **int df(const char *path)** finsh函数命令的stafts接口,打印存储设备的容量和剩余空间信息。使能了MSH后,此函数未被使用 - **dfs_file.c** dfs文件系统层对于文件相关的处理接口函数,具体实现会分别调用对应实际文件系统的操作函数接口。既dfs面向下层文件系统的接口,移植具体文件系统的时候需要实现对接代码(用RTT移植的时候,RTT已经完成了此接口,在dfs_elm.c内)。 - **int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)** 按照flags属性打开path指定文件或文件夹,然后由fd文件句柄返回 - **int dfs_file_close(struct dfs_fd *fd)** 关闭fd指定的文件或文件夹 - **int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args)** dfs层的ioctl内部接口,可读取和设置文件flags。并调用具体文件系统的ioctl接口实现底层具体功能 - **int dfs_file_read(struct dfs_fd *fd, void *buf, size_t len)** dfs层的read接口,调用具体文件系统的read接口实现读取功能 - **int dfs_file_getdents(struct dfs_fd *fd, struct dirent *dirp, size_t nbytes)** 根据文件操作符,读取dirent结构体对应的属性信息 - **int dfs_file_unlink(const char *path)** dfs层删除接口,调用具体文件系统的unlink接口实现文件或文件夹的删除功能 - **int dfs_file_write(struct dfs_fd *fd, const void *buf, size_t len)** dfs层的write接口,调用具体文件系统的write接口实现写入功能 - **int dfs_file_flush(struct dfs_fd *fd)** dfs层的同步接口,调用具体文件系统的flush接口实现文件的同步,既把文件句柄内的缓存数据真正写入到存储设备 - **int dfs_file_lseek(struct dfs_fd *fd, off_t offset)** dfs层的lseek接口,调用具体文件系统的lseek接口,实现对文件读取位置的移动 - **int dfs_file_stat(const char *path, struct stat *buf)** dfs层的读取文件属性接口,也会调用具体文件系统的stat接口 - **int dfs_file_rename(const char *oldpath, const char *newpath)** dfs层的rename接口,调用底层具体文件系统的rename接口,实现文件重命名 - **int dfs_file_ftruncate(struct dfs_fd *fd, off_t length)** 调用具体文件系统的ioctl接口,实现对文件fd的截断(length字节) - **void ls(const char *pathname)** finsh的ls命令函数 - **void rm(const char *filename)** finsh的rm命令函数 - **void cat(const char *filename)** finsh的cat命令函数 - **static void copyfile(const char *src, const char *dst)** dfs层实现的文件拷贝函数 - **static void copydir(const char *src, const char *dst)** dfs层实现的文件夹拷贝函数,遍历子文件夹,把所有子文件拷贝到目标文件夹 - **static const char *_get_path_lastname(const char *path)** 通过path路径,得到最后一级路径名 - **void copy(const char *src, const char *dst)** finsh的copy命令函数,调用上面的copyfile和copydir实现 - **filesystems文件夹:** dfs支持的具体文件系统,默认会有一个devfs文件夹,对应设备文件系统。开启了elm的fat文件系统模块后,会多一个elmfat文件夹,对应fatfs的代码 - **elmfat文件夹:** fatfs对应的代码,其中ff.c为fatfs代码,dfs_elm.c为RTT实现的移植代码,承上启下,完成dfs的调用接口和与fatfs对接的接口,并通过具体设备(flash,sdcard)的操作接口实现具体的功能 - **dfs_elm.c** 相对直接移植fatfs时diskio.c要实现的接口外,又多了一些和dfs层对接的接口。下面针对dfs_elm.c下的接口函数做简单说明 - **static int elm_result_to_dfs(FRESULT result)** 做fatfs下的返回状态与dfs下的返回状态的转换 - **static int get_disk(rt_device_t id)** 根据设备ID,在挂载的磁盘列表中找到磁盘列表ID - **int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)** 承上启下,连接dfs层和fatfs内的mount接口,实现设备挂载,把设备ID添加到挂载的磁盘列表内 - **int dfs_elm_unmount(struct dfs_filesystem *fs)** 承上启下,连接dfs层和fatfs内的unmount接口,实现设备取消挂载,把设备ID从磁盘列表中删除 - **int dfs_elm_mkfs(rt_device_t dev_id)** 承上启下,连接dfs层和fatfs内的mkfs接口,实现存储设备的格式化 - **int dfs_elm_statfs(struct dfs_filesystem *fs, struct statfs *buf)** 承上启下,连接dfs层和fatfs内的statfs和getfree接口,读取文件系统的存储空间信息 - **int dfs_elm_open(struct dfs_fd *file)** 承上启下,连接dfs层和fatfs内的open或opendir接口,实现打开文件或文件夹功能 - **int dfs_elm_close(struct dfs_fd *file)** 承上启下,连接dfs层和fatfs内的close接口,实现关闭文件或文件夹功能 - **int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args)** 承上启下,连接dfs层和fatfs内的ioctl接口,实现文件截断功能 - **int dfs_elm_read(struct dfs_fd *file, void *buf, size_t len)** 承上启下,连接dfs层和fatfs内的read接口,实现文件读取功能 - **int dfs_elm_write(struct dfs_fd *file, const void *buf, size_t len)** 承上启下,连接dfs层和fatfs内的write接口,实现文件写入功能 - **int dfs_elm_flush(struct dfs_fd *file)** 承上启下,连接dfs层和fatfs内的flush和sync接口,实现文件的同步功能,把缓存数据写入磁盘 - **int dfs_elm_lseek(struct dfs_fd *file, rt_off_t offset)** 承上启下,连接dfs层和fatfs内的lseek或seekdir接口,实现文件或文件夹的操作位置移动 - **int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)** 承上启下,调用fatfs的readdir接口,实现dfs层的getdents接口,读取文件dirent属性 - **int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)** 承上启下,连接dfs层和fatfs内的funlink接口,实现文件的删除功能 - **int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *newpath)** 承上启下,连接dfs层和fatfs内的rename接口,实现改文件名的功能 - **int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)** 承上启下,连接dfs层和fatfs内的stat接口,实现读取文件stat信息的功能 - **int elm_init(void)** 调用dfs层的dfs_register接口,把“elm”的文件系统操作接口注册到dfs文件系统中。用于后面按照“elm”类型挂载实际的存储设备。此函数被RTT加入到了组件初始化列表,会自动运行,无需用户调用 - **DSTATUS disk_initialize(BYTE drv)** 此函数为fatfs的初始化磁盘设备的接口,由于RTT实际初始化磁盘设备的代码也被加入到了自动初始化列表,所以此接口直接返回OK即可 - **DSTATUS disk_status(BYTE drv)** 此函数为fatfs读取磁盘设备状态的接口。RTT的移植,并没有对此函数做具体实现,直接返回的OK - **DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, UINT count)** 此函数为fatfs读取磁盘扇区数据的接口,对接具体的设备驱动读取接口 - **DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, UINT count)** 此函数为fatfs写入磁盘扇区数据的接口,对接具体的设备驱动写入接口 - **DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff)** 此函数为fatfs的ioctl接口,对接具体设备驱动的control接口 - **DWORD get_fattime(void)** 此函数为fatfs获取系统时间的接口,用于记录文件和文件夹的创建和修改时间 - **int ff_cre_syncobj(BYTE drv, FF_SYNC_t *m)** 如开启文件重入功能,则需要实现重入保护相关代码,RTT利用互斥量实现,此接口创建互斥量。FF_SYNC_t到rt_mutex_t的重定义在ffconf.h中定义 - **int ff_del_syncobj(FF_SYNC_t m)** fatfs的删除互斥量的接口 - **int ff_req_grant(FF_SYNC_t m)** fatfs的获取互斥量的接口 - **void ff_rel_grant(FF_SYNC_t m)** fatfs的释放互斥量的接口 - **void *ff_memalloc(UINT size)** 当定义FF_USE_LFN == 3的时候,长文件名需要在堆上面开辟空间,此时需要实现fatfs开辟存储空间的接口,对应rt_malloc接口 - **void ff_memfree(void *mem)** fatfs释放存储空间的接口,对应rt_free接口 ## dfs以fatfs系统挂载sdcard相关代码调用时序图: 大致按照从底层到顶层的初始化过程: sdio硬件外设初始化(自动): ![image.png](https://oss-club.rt-thread.org/uploads/20220430/d350e0bce4bd66c53bb6292ae7200546.png.webp) mmcsd设备初始化(自动): ![image.png](https://oss-club.rt-thread.org/uploads/20220430/6470971bc8d1c31c992fa48f1ed82b44.png.webp) fatfs文件系统初始化(自动): ![image.png](https://oss-club.rt-thread.org/uploads/20220430/d6aaf1ba22116102e4cec11a3812bba6.png) dfs文件系统初始化(自动): ![image.png](https://oss-club.rt-thread.org/uploads/20220430/b5eb36e0223cacb63ae7848340b5714f.png) sdcard检测线程,检测是否有sdcard或mmccard插入到sd卡槽并进行卡识别: ![image.png](https://oss-club.rt-thread.org/uploads/20220430/ab2fe6608c7e664ef9a7074a67829ff7.png.webp) sdcard挂载到dfs系统(用户调用): ![image.png](https://oss-club.rt-thread.org/uploads/20220430/e66cb96eaa80e8eb8d7c164b38e05101.png) ##具体使用过程 如上所述,其实在RTThread平台上使用DFS文件系统挂载SD卡已经很简单了,大致分一下几步: 1、用CubeMX生成SDIO的最底层外设初始化代码HAL_SD_MspInit(),复制到board.c - SDIO配置如下: ![SDIO配置.png](https://oss-club.rt-thread.org/uploads/20220430/acb8e39009c2b53755b52551ecc497cc.png) - SDIO的DMA配置如下: ![SDIO_DMA配置.png](https://oss-club.rt-thread.org/uploads/20220430/cd139ec3ce986fc52bcebebcaea42aa0.png) - SDIO的NVIC配置如下: ![SDIO_NVIC配置.png](https://oss-club.rt-thread.org/uploads/20220430/779281ba091c03cd9a7de652954d1284.png) 生成代码如下(复制到board.c): ```C SD_HandleTypeDef hsd; DMA_HandleTypeDef hdma_sdio_rx; DMA_HandleTypeDef hdma_sdio_tx; /** * @brief SD MSP Initialization * This function configures the hardware resources used in this example * @param hsd: SD handle pointer * @retval None */ void HAL_SD_MspInit(SD_HandleTypeDef* hsd) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hsd->Instance==SDIO) { /* USER CODE BEGIN SDIO_MspInit 0 */ /* USER CODE END SDIO_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SDIO_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /**SDIO GPIO Configuration PC8 ------> SDIO_D0 PC9 ------> SDIO_D1 PC10 ------> SDIO_D2 PC11 ------> SDIO_D3 PC12 ------> SDIO_CK PD2 ------> SDIO_CMD */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 |GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* SDIO DMA Init */ /* SDIO_RX Init */ hdma_sdio_rx.Instance = DMA2_Stream3; hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4; hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdio_rx.Init.Mode = DMA_PFCTRL; hdma_sdio_rx.Init.Priority = DMA_PRIORITY_LOW; hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4; hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4; if (HAL_DMA_Init(&hdma_sdio_rx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(hsd,hdmarx,hdma_sdio_rx); /* SDIO_TX Init */ hdma_sdio_tx.Instance = DMA2_Stream6; hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4; hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdio_tx.Init.Mode = DMA_PFCTRL; hdma_sdio_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4; hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4; if (HAL_DMA_Init(&hdma_sdio_tx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(hsd,hdmatx,hdma_sdio_tx); /* SDIO interrupt Init */ HAL_NVIC_SetPriority(SDIO_IRQn, 6, 0); HAL_NVIC_EnableIRQ(SDIO_IRQn); /* USER CODE BEGIN SDIO_MspInit 1 */ /* USER CODE END SDIO_MspInit 1 */ } } ``` 2、用RTThreadStudio配置DFS组件和Fatfs组件: - Studio组件配置如下,如只需移植Fatfs挂载SD卡,则只需开启“DFS”,“Fatfs”和“SDIO”即可,最大扇区也可以用默认的512,我的是同时挂载了SPI接口的串行Flash,Flash的扇区是4096,所以修改了一下这个参数: ![RTThread组件配置.png](https://oss-club.rt-thread.org/uploads/20220430/71b9d50f0ee5d70df0b5c43a29719ffe.png.webp) ![RTThread组件参数配置.png](https://oss-club.rt-thread.org/uploads/20220430/95c14baf00fa9f82503ba3a35a8523e5.png.webp) 3、挂载设备到文件系统: - 如上所述,在RTThread平台上使用DFS,只要配置好组件(代码里面就是宏定义),基本所有的初始化代码都会自动调用,无需用户干涉。这里用户只需要找到SD卡设备,然后挂载即可。 ```C #define SDCardPath "/sdcard0" void sdmnt(void) { int sta; if(rt_device_find("sd0") != RT_NULL) { sta = dfs_mount("sd0", SDCardPath, "elm", 0, 0); if(sta == RT_EOK) { LOG_I("sd card mount to SDCardPath"); } else { LOG_W("sd card mount to SDCardPath failed!"); } } } MSH_CMD_EXPORT(sdmnt, mount the sd card to local filesystem); ``` 4、挂载后就可以按照dfs_posix.c里面的通用接口进行调用使用了。当然,dfs已经实现了很多基于命令行的操作命令,比如“cd”,“ls”,“cat”等。使用方法基本和linux下差不太多,但功能上确实还是没那么强大,这也是很正常的,如果也做那么强大,岂不是又变成了和linux一个量级的系统了,失去了轻量级可抢占系统的意义了。
9
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
吉利咕噜2022
国防科大-军品研发
文章
18
回答
3
被采纳
2
关注TA
发私信
相关文章
1
代码分享,stm32f407的sdio驱动。
2
求个在STM32F103 RTT上使用SDIO接口的例子
3
是否能增加一个 SDIO AP61xx 的驱动呢
4
sdio和fsmc驱动lcd冲突
5
发现了sdio_unregister_driver里的一个bug
6
用sdio框架驱动过w8801(wifi模块)的坛友请进(已解决)
7
关于rt-thread系统sdio驱动框架使用
8
问题请教,关于在rt-thread中调试RT1052中调试sdio wifi模块
9
【文件系统学习】+海中陆地+RT-Thread文件系统学习挂载SDIO...
10
sdio驱动是怎么使用的?也没有文档和例程啊
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
8
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
9
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
4
次点赞
Ghost_Girls
1
篇文章
7
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部