赞
踩
RT-Thread–很好的一款rtos,各种组件齐全。本文旨在记录下对RT-Thread的文件系统初识。进而引申思考linux下的vfs是否也类似于此。
近来自忖采用sd卡作为大量数据的载体,以便在没有网络支持的场景下,保存嵌入式系统运行的记录及数据。RT-Thread下正好集成了sd卡驱动,又支持fat文件系统,幸甚!
RT-Thread本身支持对文件的posix接口,同在linux上一样,open、write等即可完成对文件操作,数据即可以文件形式保存。本文全当文件系统搭建过程的记录,以及对RT-Thread文件系统的浅要分析。
自此切入正题,不去赘述RT-Thread相关的东西,也不去赘述sd卡相关blabla。。。。。。
RT-Thread中使用文件系统大致分为以下步骤:dfs_init()、elm_init()、dfs_mount()。
dfs_init:初始化rtos的系统文件。
elm_init:初始化fat文件系统接口层。
dfs_mount:挂载sd卡到指定文件系统。
好,先跑代码,再理头绪。
/**
* @addtogroup DFS
*/
/*@{*/
/**
* this function will initialize device file system.
*/
int dfs_init(void)
{
/* clear filesystem operations table */
rt_memset((void *)filesystem_operation_table, 0, sizeof(filesystem_operation_table));
/* clear filesystem table */
rt_memset(filesystem_table, 0, sizeof(filesystem_table));
/* clean fd table */
rt_memset(fd_table, 0, sizeof(fd_table));
/* create device filesystem lock */
rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO);
#ifdef DFS_USING_WORKDIR
/* set current working directory */
rt_memset(working_directory, 0, sizeof(working_directory));
working_directory[0] = '/';
#endif
return 0;
}
一看就是数据初始化的工作嘛,对filesystem_operation_table、filesystem_table、fd_table有个印象,往下看自然就知道都是干嘛用的。
int elm_init(void)
{
/* register fatfs file system */
dfs_register(&dfs_elm);
return 0;
}
其实,这里是将fat注册进了filesystem_operation_table,而不是filesystem_table。
int dfs_mount(const char *device_name,
const char *path,
const char *filesystemtype,
unsigned long rwflag,
const void *data)
dfs_mount("sd0", "/", "elm", 0, NULL)
此部分作用就是:把一个设备与某个文件系统结合挂载到某个路径下。此处就是:把sd卡0与fat文件系统结合挂载到“/”该路径下。然后就可以用posix读写sd卡了。简单的不要不要的。
巴特,为什么文件系统名称为“elm”,不叫“fat”之类。
dfs_mount看下源码其实就明白了,设备挂载就是根据filesystemtype去filesystem_operation_table表中找匹配的文件系统,匹配之后再将文件系统加入filesystem_table中。
最后以一次open操作理清流程结束本文。
open操作会调用dfs的相关open操作,dfs定义统一的文件系统接口。根据open的path去查找次路径下的文件系统,并调用该文件系统对应的open操作,也就是elm的open操作,elm再调用fat文件系统的open操作。最后涉及到sd卡的读写再回调elm中的设备操作,最后再是调用sd卡的操作接口完成。
1,dfs就是RT-Thread的虚拟文件系统,像linux的vfs一样;
2,dfs以统一操作接口封装不同文件系统的差异;
3,文件系统(如:fat)挂载后,就是rtos知道有这么文件系统,但还无法使用。(没有物理设备,你往哪写数据)
4,设备挂载后与文件系统配对挂载到一个特定路径。(这点和linux好像)
5,文件操作时,根据路径就能找到所属的具体文件系统。
6,elm是啥玩意儿?elm就是fat接入dfs的连接件。由于fat不是针对RT-Thread的,rtos作者本人也没有修改出一稿RT-Thread专用的fat源码,所有就有了elm这一层。其实elm就可以看作是RT-Thread下的fat文件系统–封装fat操作并提供底层硬件操作回调。
7,关于sd卡驱动,RT-Thread有设备驱动接口,本文不涉及了。
8,总的来说dfs这部分不难,同时可能对后续了解linux的vfs时会有些帮助。
1,我RT-Thread-1.2.2版木有文件的flush接口,也就是只有文件close的时候数据才会被刷到sd卡中,写入的数据size足够大时估计也会自动flush。但是如果希望每次写少量数据也能及时刷到sd卡中,但又不想每次写入都执行一遍open、close。然后么就是修改下dfs的write操作了
int dfs_file_write(struct dfs_fd *fd, const void *buf, rt_size_t len)
{
struct dfs_filesystem *fs;
if (fd == RT_NULL)
return -DFS_STATUS_EINVAL;
fs = fd->fs;
if (fs->ops->write == RT_NULL)
return -DFS_STATUS_ENOSYS;
//return fs->ops->write(fd, buf, len);
/*为了flush而添加 by 百里无异 at 2016-3-4*/
int ret = fs->ops->write(fd, buf, len);
if (ret > 0) {
dfs_file_flush(fd);
}
return ret;
/******/
正确的做法用该是在posix接口中添加flush操作,这里偷懒了!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。