1@page vfs vfs
2
3[更正文档](https://gitee.com/alios-things/vfs/edit/master/README.md)      [贡献说明](https://help.aliyun.com/document_detail/302301.html)
4
5# 概述
6VFS 虚拟文件系统为各种文件(包括设备文件和普通文件)提供统一的操作接口。它是具体设备文件和文件系统之上的抽象层。其目的是允许应用程序以统一的方式访问不同类型的具体文件和设备。用户可以将ramfs,little fs等具体的文件系统注册到 VFS 中,然后使用标准操作接口(open,read,write,close 等)访问其中的文件。
7
8组件支持以下功能:
9
10- 普通文件操作
11- 设备文件操作
12- inode 管理
13- 文件描述符管理
14
15## 版权信息
16> Apache license v2.0
17
18## 目录结构
19```tree
20├── src
21│   ├── vfs_adapt.c   # vfs OS adapt layer 具体实现代码
22│   ├── vfs_aos.c     # VFS 的aos api接口实现
23│   ├── vfs.c         # vfs 核心逻辑代码
24│   ├── vfs_file.c    # vfs file descriptor 管理具体实现代码
25│   └── vfs_inode.c   # vfs inode 管理代码
26├── include
27│   ├── aos
28│   │   └── vfs.h     # VFS的对外AOS API
29|   ├── vfs_api.h     # VFS的对外 API
30|   ├── vfs_conf.h    # VFS 的参数配置
31|   ├── vfs_file.h    # VFS 文件相关操作
32|   ├── vfs_inode.h   # VFS inode 管理
33|   ├── vfs_types.h   # VFS 数据结构定义
34│   └── vfs_adapt.h   # vfs OS adapt layer declaration
35├── package.yaml      # 编译配置文件
36└── example
37    └── vfs_example.c # VFS 示例代码
38```
39
40## 依赖组件
41
42* 无
43
44# 常用配置
45系统中相关配置已有默认值,如需修改配置,统一在yaml中**def_config**节点修改,具体如下:
46> VFS 设备node数量,默认4096,  可修改yaml配置如:
47```yaml
48def_config:
49  VFS_CONFIG_DEVICE_NODES: 4096
50```
51> VFS FD 默认起始值,默认 512,可修改yaml配置如:
52```yaml
53def_config:
54  VFS_CONFIG_FD_OFFSET: 512
55```
56> VFS 路径长度最大字节数,默认256,可修改yaml配置如:
57```yaml
58def_config:
59  VFS_CONFIG_PATH_MAX: 256
60```
61> VFS 最大文件数量,默认50,可修改yaml配置如:
62```yaml
63def_config:
64  VFS_CONFIG_MAX_FILE_NUM: 50
65```
66# API说明
67
68## 初始化虚拟文件系统
69
70```C
71int vfs_init(void);
72```
73
74* 参数
75  * 无
76* 返回值
77  * 0:成功
78  * < 0:失败
79
80## 通过路径打开文件
81
82```C
83int aos_open(const char *path, int flags);
84```
85
86* 参数
87  * path: 文件或者设备的路径
88  * flags: 打开操作模式
89* 返回值
90  * 文件描述符:成功
91  * < 0:失败
92
93* flags:
94
95| 参数     | 描述                                                         |
96| -------- | ------------------------------------------------------------ |
97| O_RDONLY | 只读方式打开文件                                             |
98| O_WRONLY | 只写方式打开文件                                             |
99| O_RDWR   | 以读写方式打开文件                                           |
100| O_CREAT  | 如果要打开的文件不存在,则建立该文件                         |
101| O_APPEND | 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式添加到文件的尾部 |
102| O_TRUNC  | 如果文件已经存在,则清空文件中的内容                         |
103| O_EXCL   | 如果存在指定文件,返回出错                                   |
104
105## 关闭文件
106
107```C
108int aos_close(int fd);
109```
110
111* 参数
112  * fd: 文件描述符
113* 返回值
114  * 0:成功
115  * < 0:失败
116
117## 读取文件内容
118
119```C
120ssize_t aos_read(int fd, void *buf, size_t nbytes);
121```
122
123* 参数
124  * fd: 文件描述符
125  * nbytes: 需要读取的字节数
126  * buf: 读取到缓冲区的指针
127* 返回值
128  * 实际读取到的字节数
129  * 0:读取数据到达文件结尾
130  * < 0:失败
131
132## 向文件写入内容
133
134```C
135ssize_t aos_write(int fd, const void *buf, size_t nbytes);
136```
137
138* 参数
139  * fd: 文件描述符
140  * nbytes: 需要写入的字节数
141  * buf: 数据缓冲区的指针
142* 返回值
143  * 实际写入的字节数
144  * < 0:失败
145
146## 发送特定命令控制接口
147
148```C
149int aos_ioctl(int fd, int cmd, unsigned long arg);
150```
151
152* 参数
153  * fd: 文件描述符
154  * cmd: 特定控制命令
155  * arg: 命令的参数
156* 返回值
157  * 任何返回值
158
159## 在打开的文件描述符上执行下面描述的操作,操作由 cmd 确定
160
161```C
162int aos_fcntl(int fd, int cmd, int val);
163```
164
165* 参数
166  * fd: 文件描述符
167  * cmd: 文件操作命令
168  * val: 依赖`cmd`的参数
169* 返回值
170  * 0:成功
171  * < 0: 失败
172
173## 设置下次读取文件的位置
174
175```C
176off_t aos_lseek(int fd, off_t offset, int whence);
177```
178
179* 参数
180  * fd: 文件描述符
181  * offset: 根据参数`whence`来移动读写位置的位移数
182  * whence: SEEK_SET 参数`offset` 即为新的读写位置
183  *         SEEK_CUR 以目前的读写位置往后增加`offset` 个位移量
184  *         SEEK_END 将读写位置指向文件尾后再增加`offset`个位移量. 当whence 值为SEEK_CUR 或SEEK_END 时, 参数`offet`允许负值的出现.
185* 返回值
186  * 返回新的读写位置
187
188## 同步文件
189
190```C
191int aos_sync(int fd);
192```
193
194* 参数
195  * fd: 文件描述符
196* 返回值
197  * 0:成功
198  * < 0: 失败
199
200## 获取文件状态
201
202```C
203int aos_stat(const char *path, struct stat *st);
204```
205
206* 参数
207  * path: 文件名
208  * st: 结构指针,指向一个存放文件状态信息的结构体
209* 返回值
210  * 0:成功
211  * < 0: 失败
212
213## 删除指定目录下的文件
214
215```C
216int aos_unlink(const char *path);
217```
218
219* 参数
220  * path: 要删除文件的路径
221* 返回值
222  * 0:成功
223  * < 0: 失败
224
225## 重命名文件
226
227```C
228int aos_rename(const char *oldpath, const char *newpath);
229```
230
231* 参数
232  * oldpath: 旧文件名
233  * newpath: 新文件名
234* 返回值
235  * 0:成功
236  * < 0: 失败
237
238## 打开目录
239
240```C
241aos_dir_t *aos_opendir(const char *path);
242```
243
244* 参数
245  * path: 目录名
246* 返回值
247  * 目录流指针: 成功
248  * NULL: 失败
249
250## 关闭目录
251
252```C
253int aos_closedir(aos_dir_t *dir);
254```
255
256* 参数
257  * dir: 目录流指针
258* 返回值
259  * 0: 成功
260  * < 0: 失败
261
262## 读取下个目录
263
264```C
265aos_dirent_t *aos_readdir(aos_dir_t *dir);
266```
267
268* 参数
269  * dir: 目录流指针
270* 返回值
271  * 目录流指针: 成功
272  * NULL: 已读到目录尾部
273
274## 创建目录
275
276```C
277int aos_mkdir(const char *path);
278```
279
280* 参数
281  * path: 目录名
282* 返回值
283  * 0: 成功
284  * < 0: 失败
285
286## 删除目录
287
288```C
289int aos_rmdir(const char *path);
290```
291
292* 参数
293  * path: 目录名
294* 返回值
295  * 0: 成功
296  * < 0: 失败
297
298# 使用示例
299组件使用示例相关的代码下载、编译和固件烧录均依赖AliOS Things配套的开发工具,所以首先需要参考[《AliOS Things集成开发环境使用说明之搭建开发环境》](https://help.aliyun.com/document_detail/302378.html),下载安装。
300待开发环境搭建完成后,可以按照以下步骤进行示例的测试。
301
302## 步骤1 创建或打开工程
303
304**打开已有工程**
305
306如果用于测试的案例工程已存在,可参考[《AliOS Things集成开发环境使用说明之打开工程》](https://help.aliyun.com/document_detail/302381.html)打开已有工程。
307
308**创建新的工程**
309
310组件的示例代码可以通过编译链接到AliOS Things的任意案例(solution)来运行,这里选择helloworld_demo案例。helloworld_demo案例相关的源代码下载可参考[《AliOS Things集成开发环境使用说明之创建工程》](https://help.aliyun.com/document_detail/302379.html)311
312## 步骤2 添加组件
313
314案例下载完成后,需要在helloworld_demo组件的package.yaml中添加对组件的依赖:
315> 在helloworld_demo组件的package.yaml中添加
316```yaml
317depends:
318  - vfs: master # helloworld_demo中引入vfs组件
319```
320
321## 步骤3 下载组件
322
323在已安装了  的开发环境工具栏中,选择Terminal -> New Terminal启动终端,并且默认工作路径为当前工程的workspace,此时在终端命令行中输入:
324
325```shell
326
327aos install vfs
328
329```
330
331上述命令执行成功后,组件源码则被下载到了./components/vfs路径中。
332
333## 步骤4 添加示例
334
335> vfs组件的package.yaml中添加[example示例代码](https://gitee.com/alios-things/vfs/tree/master/example)336```yaml
337source_file:
338  - "example/vfs_example.c" # add vfs_example.c
339```
340
341## 步骤5 编译固件
342
343在示例代码已经添加至组件的配置文件,并且helloworld_demo已添加了对该组件的依赖后,就可以编译helloworld_demo案例来生成固件了,具体编译方法可参考[《AliOS Things集成开发环境使用说明之编译固件》](https://help.aliyun.com/document_detail/302384.html)344
345## 步骤6 烧录固件
346
347helloworld_demo案例的固件生成后,可参考[《AliOS Things集成开发环境使用说明之烧录固件》](https://help.aliyun.com/document_detail/302383.html)来烧录固件。
348
349## 步骤7 打开串口
350
351固件烧录完成后,可以通过串口查看示例的运行结果,打开串口的具体方法可参考[《AliOS Things集成开发环境使用说明之查看日志》](https://help.aliyun.com/document_detail/302382.html)352
353当串口终端打开成功后,可在串口中输入help来查看已添加的测试命令。
354
355## 步骤8 测试示例
356
357> CLI命令行输入:
358```sh
359vfs_example
360```
361
362> 关键日志:
363```sh
364vfs example test success!
365```
366
367