Skip to content

Commit e41746e

Browse files
committed
Merge branch 'docs/update_cn_vfs' into 'master'
docs: Update CN translation for vfs.rst Closes DOC-9550 See merge request espressif/esp-idf!35265
2 parents 5462240 + 3ca973d commit e41746e

File tree

2 files changed

+73
-49
lines changed

2 files changed

+73
-49
lines changed

docs/en/api-reference/storage/vfs.rst

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ For example, one can mount a FAT filesystem driver at the ``/fat`` prefix and ca
1717
FS Registration
1818
---------------
1919

20-
.. note:: For previous version of the API (using :cpp:type:`esp_vfs_t`) see documentation for previous release.
20+
.. note::
21+
22+
For previous version of the API (using :cpp:type:`esp_vfs_t`), see documentation for previous release.
2123

2224
To register an FS driver, an application needs to define an instance of the :cpp:type:`esp_vfs_fs_ops_t` structure and populate it with function pointers to FS APIs:
2325

@@ -44,7 +46,7 @@ To register an FS driver, an application needs to define an instance of the :cpp
4446
Non-static :cpp:type:`esp_vfs_fs_ops_t`
4547
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4648

47-
The recommended approach for registering filesystem is to use statically allocated :cpp:type:`esp_vfs_fs_ops_t` alongside ``ESP_VFS_FLAG_STATIC``, as it is more memory efficient. In cases where using static allocation is not possible, ``ESP_VFS_FLAG_STATIC`` can replaced with ``ESP_VFS_FLAG_DEFAULT``. This tells VFS to make a deep copy of the passed structure in RAM, this copy will be managed by VFS component.
49+
The recommended approach for registering filesystem is to use statically allocated :cpp:type:`esp_vfs_fs_ops_t` alongside ``ESP_VFS_FLAG_STATIC``, as it is more memory efficient. In cases where using static allocation is not possible, ``ESP_VFS_FLAG_STATIC`` can be replaced with ``ESP_VFS_FLAG_DEFAULT``. This tells VFS to make a deep copy of the passed structure in RAM, this copy will be managed by VFS component.
4850

4951
.. highlight:: c
5052

@@ -68,10 +70,10 @@ The recommended approach for registering filesystem is to use statically allocat
6870
}
6971

7072

71-
Context aware filesystem
73+
Context Aware Filesystem
7274
^^^^^^^^^^^^^^^^^^^^^^^^
7375

74-
In some cases it might be beneficial, or even necessary to pass some context to the filesystem functions, such as mountpoint specific file descriptor table, when multiple instances of FS mounted. For this reason the :cpp:type:`esp_vfs_fs_ops_t` contains second version of each member with ``_p`` suffix, for example for ``read`` there is ``read_p``, these functions have additional first argument. When registering the FS, ``ESP_VFS_FLAG_CONTEXT_PTR`` needs to be specified and the pointer passed as the last argument.
76+
In some cases, it might be beneficial or even necessary to pass some context to the filesystem functions, such as a mountpoint-specific file descriptor table, when multiple instances of FS are mounted. For this reason, :cpp:type:`esp_vfs_fs_ops_t` contains a second version of each member with ``_p`` suffix; for example, ``read`` function has a corresponding ``read_p`` function. These functions take an additional first argument. When registering the FS, ``ESP_VFS_FLAG_CONTEXT_PTR`` needs to be specified and the context pointer should be passed as the last argument.
7577

7678
::
7779

@@ -81,7 +83,7 @@ In some cases it might be beneficial, or even necessary to pass some context to
8183
.write_p = &myfs_write,
8284
// ... other members initialized
8385

84-
// When registering FS, pass the ESP_VFS_FLAG_CONTEXT_PTR flag, alongside FS context pointer into the third argument
86+
// When registering FS, pass the ESP_VFS_FLAG_CONTEXT_PTR flag, alongside FS context pointer as the third and fourth arguments, respectively
8587
// (hypothetical myfs_mount function is used for illustrative purposes)
8688
myfs_t* myfs_inst1 = myfs_mount(partition1->offset, partition1->size);
8789
ESP_ERROR_CHECK(esp_vfs_register_fs("/data1", &myfs, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, myfs_inst1));
@@ -228,9 +230,9 @@ Well Known VFS Devices
228230

229231
IDF defines several VFS devices that can be used by applications. These devices are, among others:
230232

231-
* ``/dev/uart/<UART NUMBER>`` - file mapping to an UART opened with the VFS driver. The UART number is the number of the UART peripheral.
232-
* ``/dev/null`` - file that discards all data written to it and returns EOF when read. It is automatically created if :ref:`CONFIG_VFS_INITIALIZE_DEV_NULL` is enabled.
233-
* ``/dev/console`` - file that is connected to the primary and secondary outputs specified in the menuconfig by :ref:`CONFIG_ESP_CONSOLE_UART` and :ref:`CONFIG_ESP_CONSOLE_SECONDARY` respectively. More information can be found here :doc:`../../api-guides/stdio`.
233+
* ``/dev/uart/<UART NUMBER>`` - file mapping to an UART opened with the VFS driver. The UART number is the number of the UART peripheral.
234+
* ``/dev/null`` - file that discards all data written to it and returns EOF when read. It is automatically created if :ref:`CONFIG_VFS_INITIALIZE_DEV_NULL` is enabled.
235+
* ``/dev/console`` - file that is connected to the primary and secondary outputs specified in the menuconfig by :ref:`CONFIG_ESP_CONSOLE_UART` and :ref:`CONFIG_ESP_CONSOLE_SECONDARY` respectively. More information can be found here :doc:`../../api-guides/stdio`.
234236

235237

236238
Application Examples

docs/zh_CN/api-reference/storage/vfs.rst

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,98 @@
33

44
:link_to_translation:`en:[English]`
55

6+
67
概述
78
--------
89

910
虚拟文件系统 (VFS) 组件为驱动程序提供一个统一接口,可以操作类文件对象。这类驱动程序可以是 FAT、SPIFFS 等真实文件系统,也可以是提供文件类接口的设备驱动程序。
1011

11-
VFS 组件支持 C 库函数(如 fopen 和 fprintf 等)与文件系统 (FS) 驱动程序协同工作。在高层级,每个 FS 驱动程序均与某些路径前缀相关联。当一个 C 库函数需要打开文件时,VFS 组件将搜索与该文件所在文件路径相关联的 FS 驱动程序,并将调用传递给该驱动程序。针对该文件的读取、写入等其他操作的调用也将传递给这个驱动程序。
12+
VFS 组件支持 C 库函数(如 fopen 和 fprintf 等)与文件系统 (FS) 驱动程序协同工作。在高层级,每个 FS 驱动程序均挂载到以某个前缀开头的路径上。当一个 C 库函数需要打开文件时,VFS 组件将搜索与该文件所在文件路径相关联的 FS 驱动程序,并将调用传递给该驱动程序。针对该文件的读取、写入等其他操作的调用也将传递给这个驱动程序。
1213

13-
例如,使用 ``/fat`` 前缀注册 FAT 文件系统驱动,之后即可调用 ``fopen("/fat/file.txt", "w")``。之后,VFS 将调用 FAT 驱动的 ``open`` 函数,并将参数 ``/file.txt`` 和合适的打开模式传递给 ``open`` 函数;后续对返回的 ``FILE*`` 数据流调用 C 库函数也同样会传递给 FAT 驱动。
14+
例如,将 FAT 文件系统驱动挂载到 ``/fat`` 前缀开头的路径上,之后即可调用 ``fopen("/fat/file.txt", "w")``。之后,VFS 将调用 FAT 驱动的 ``open`` 函数,并将参数 ``/file.txt`` 和合适的打开模式传递给 ``open`` 函数;后续对返回的 ``FILE*`` 数据流调用 C 库函数也同样会传递给 FAT 驱动。
1415

1516

1617
注册 FS 驱动程序
1718
---------------------
1819

19-
如需注册 FS 驱动程序,应用程序首先要定义一个 :cpp:type:`esp_vfs_t` 结构体实例,并用指向 FS API 的函数指针填充它。
20+
.. note::
21+
22+
有关先前版本 API(使用 :cpp:type:`esp_vfs_t`)的内容,可以查阅之前发布的文档。
23+
24+
如需注册 FS 驱动程序,应用程序首先要定义一个 :cpp:type:`esp_vfs_fs_ops_t` 结构体实例,并用指向 FS API 的函数指针填充它。
2025

2126
.. highlight:: c
2227

2328
::
2429

25-
esp_vfs_t myfs = {
26-
.flags = ESP_VFS_FLAG_DEFAULT,
30+
// esp_vfs_fs_ops_t 及其子组件的声明必须是静态的
31+
static const esp_vfs_dir_ops_t myfs_dir = {
32+
.fstat = &myfs_fstat,
33+
};
34+
35+
static const esp_vfs_fs_ops_t myfs = {
2736
.write = &myfs_write,
2837
.open = &myfs_open,
29-
.fstat = &myfs_fstat,
3038
.close = &myfs_close,
3139
.read = &myfs_read,
40+
.dir = &myfs_dir,
3241
};
3342

34-
ESP_ERROR_CHECK(esp_vfs_register("/data", &myfs, NULL));
43+
ESP_ERROR_CHECK(esp_vfs_register_fs("/data", &myfs, ESP_VFS_FLAG_STATIC, NULL));
3544

36-
在上述代码中需要用到 ``read``、 ``write`` 或 ``read_p``、 ``write_p``,具体使用哪组函数由 FS 驱动程序 API 的声明方式决定。
3745

38-
示例 1:声明 API 函数时不带额外的上下文指针参数,即 FS 驱动程序为单例模式,此时使用 ``write`` ::
46+
非静态 :cpp:type:`esp_vfs_fs_ops_t`
47+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3948

40-
ssize_t myfs_write(int fd, const void * data, size_t size);
49+
推荐使用静态分配的 :cpp:type:`esp_vfs_fs_ops_t` 和 ``ESP_VFS_FLAG_STATIC`` 来注册文件系统,因为这种方式更高效。若无法使用静态分配,则将 ``ESP_VFS_FLAG_STATIC`` 替换为 ``ESP_VFS_FLAG_DEFAULT``,指示 VFS 在 RAM 中对传递的结构体进行深拷贝,并由 VFS 组件来管理这份拷贝。
4150

42-
// 在 esp_vfs_t 的定义中:
43-
.flags = ESP_VFS_FLAG_DEFAULT,
44-
.write = &myfs_write,
45-
// ... 其他成员已初始化
51+
.. highlight:: c
52+
53+
::
54+
55+
// 可能是局部作用域
56+
{
57+
esp_vfs_dir_ops_t myfs_dir = {
58+
.fstat = &myfs_fstat,
59+
};
60+
61+
bool some_condition = false;
62+
63+
esp_vfs_fs_ops_t myfs = {
64+
.write = some_condition ? &myfs_special_write : &myfs_write,
65+
// ... 其他成员
66+
.dir = &myfs_dir,
67+
};
4668

47-
// 注册文件系统时,上下文指针(第三个参数)为 NULL
48-
ESP_ERROR_CHECK(esp_vfs_register("/data", &myfs, NULL));
69+
ESP_ERROR_CHECK(esp_vfs_register_fs("/data", &myfs, ESP_VFS_FLAG_DEFAULT, NULL));
70+
}
4971

50-
示例 2:声明 API 函数时需要一个额外的上下文指针作为参数,即可支持多个 FS 驱动程序实例,此时使用 ``write_p`` ::
72+
73+
上下文感知文件系统
74+
^^^^^^^^^^^^^^^^^^
75+
76+
在某些情况下,当挂载多个文件系统实例时,向文件系统功能传递一些上下文信息(比如特定挂载点的文件描述符表)是有益的,甚至是必要的。因此,:cpp:type:`esp_vfs_fs_ops_t` 中包含了每个成员带有 ``_p`` 后缀的第二个版本。例如,``read`` 函数有其对应的 ``read_p`` 函数,后者需要额外的第一个参数。在注册文件系统时,必须指定 ``ESP_VFS_FLAG_CONTEXT_PTR`` 标志,并将上下文指针作为最后一个参数传递。
77+
78+
::
5179

5280
ssize_t myfs_write(myfs_t* fs, int fd, const void * data, size_t size);
5381

5482
// 在 esp_vfs_t 的定义中:
55-
.flags = ESP_VFS_FLAG_CONTEXT_PTR,
5683
.write_p = &myfs_write,
57-
// ... 其他成员已初始化
84+
// ... 初始化其他成员
5885

59-
// 注册文件系统时,将文件系统上下文指针传递给第三个参数
60-
// (使用假设的 myfs_mount 函数进行示例说明
86+
// 注册文件系统时,将 ESP_VFS_FLAG_CONTEXT_PTR 标志与文件系统上下文指针分别作为第三和第四个参数传递
87+
// (假设的 myfs_mount 函数用于实例说明
6188
myfs_t* myfs_inst1 = myfs_mount(partition1->offset, partition1->size);
62-
ESP_ERROR_CHECK(esp_vfs_register("/data1", &myfs, myfs_inst1));
89+
ESP_ERROR_CHECK(esp_vfs_register_fs("/data1", &myfs, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, myfs_inst1));
6390

6491
// 可以注册另一个实例:
6592
myfs_t* myfs_inst2 = myfs_mount(partition2->offset, partition2->size);
66-
ESP_ERROR_CHECK(esp_vfs_register("/data2", &myfs, myfs_inst2));
93+
ESP_ERROR_CHECK(esp_vfs_register_fs("/data2", &myfs, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, myfs_inst2));
94+
6795

6896
同步输入/输出多路复用
69-
^^^^^^^^^^^^^^^^^^^^^^^^
97+
----------------------
7098

7199
VFS 组件支持通过 :cpp:func:`select` 进行同步输入/输出多路复用,其实现方式如下:
72100

@@ -82,16 +110,17 @@ VFS 组件支持通过 :cpp:func:`select` 进行同步输入/输出多路复用
82110

83111
6. :cpp:func:`select` 调用结束并返回适当的结果。
84112

113+
85114
非套接字 VFS 驱动
86-
""""""""""""""""""""""
115+
^^^^^^^^^^^^^^^^^
87116

88117
如果要使用非套接字 VFS 驱动的文件描述符调用 :cpp:func:`select`,那么需要用函数 :cpp:func:`start_select` 和 :cpp:func:`end_select` 注册该驱动,具体如下:
89118

90119
.. highlight:: c
91120

92121
::
93122

94-
// 在 esp_vfs_t 的定义中:
123+
// 在 esp_vfs_select_ops_t 的定义中:
95124
.start_select = &uart_start_select,
96125
.end_select = &uart_end_select,
97126
// ... 其他成员已初始化
@@ -113,7 +142,7 @@ VFS 组件支持通过 :cpp:func:`select` 进行同步输入/输出多路复用
113142

114143

115144
套接字 VFS 驱动
116-
""""""""""""""""""""""
145+
^^^^^^^^^^^^^^^
117146

118147
套接字 VFS 驱动会使用自实现的 :cpp:func:`socket_select` 函数,在读取/写入/错误条件时,非套接字 VFS 驱动会通知该函数。
119148

@@ -123,7 +152,7 @@ VFS 组件支持通过 :cpp:func:`select` 进行同步输入/输出多路复用
123152

124153
::
125154

126-
// 在 esp_vfs_t 的定义中:
155+
// 在 esp_vfs_select_ops_t 的定义中:
127156
.socket_select = &lwip_select,
128157
.get_socket_select_semaphore = &lwip_get_socket_select_semaphore,
129158
.stop_socket_select = &lwip_stop_socket_select,
@@ -146,6 +175,7 @@ VFS 组件支持通过 :cpp:func:`select` 进行同步输入/输出多路复用
146175

147176
不要在 :cpp:func:`select` 调用过程中更改套接字驱动,否则会出现一些未定义行为。
148177

178+
149179
路径
150180
-----
151181

@@ -195,24 +225,15 @@ VFS 对文件路径长度没有限制,但文件系统路径前缀受 ``ESP_VFS
195225
注意,用 ``EFD_SUPPORT_ISR`` 创建 eventfd 将导致在读取、写入文件时,以及在设置这个文件的 ``select()`` 开始和结束时,暂时禁用中断。
196226

197227

198-
精简版 VFS
199-
------------
200-
201-
为尽量减少 RAM 使用,提供了另一版本的 :cpp:func:`esp_vfs_register` 函数,即 :cpp:func:`esp_vfs_register_fs`。这个版本的函数接受 :cpp:class:`esp_vfs_fs_ops_t` 而不是 :cpp:class:`esp_vfs_t`,并且还接受按位或 (OR-ed) 的标志参数。与 :cpp:func:`esp_vfs_register` 函数不同,只要在调用时提供 ``ESP_VFS_FLAG_STATIC`` 标志,该函数就可以处理静态分配的结构体。
202-
203-
:cpp:class:`esp_vfs_fs_ops_t` 根据功能(如,目录操作、选择支持、termios 支持等)被拆分为不同的结构体。主结构体包含基本功能,如 ``read``、``write`` 等,并包含指向特定功能结构体的指针。这些指针可以设置为 ``NULL``,表示不支持该结构体中提供的所有功能,从而减少所需内存。
204-
205-
在内部,VFS 组件使用的是该版本的 API,并在注册时通过额外步骤将 :cpp:class:`esp_vfs_t` 转换为 :cpp:class:`esp_vfs_fs_ops_t`。
206-
207-
208228
常用 VFS 设备
209229
-------------
210230

211231
IDF 定义了多个可供应用程序使用的 VFS 设备。这些设备包括:
212232

213-
* ``/dev/uart/<UART NUMBER>`` - 此文件映射到使用 VFS 驱动程序打开的 UART 中。UART 编号是 UART 外设的编号。
214-
* ``/dev/null`` - 此文件丢弃所有写入的数据,并在读取时返回 EOF。启用 :ref:`CONFIG_VFS_INITIALIZE_DEV_NULL` 会自动创建此文件。
215-
* ``/dev/console`` - 此文件连接到在 menuconfig 中由 :ref:`CONFIG_ESP_CONSOLE_UART` 和 :ref:`CONFIG_ESP_CONSOLE_SECONDARY` 指定的主输出和次输出。更多信息请参考 :doc:`../../api-guides/stdio`。
233+
* ``/dev/uart/<UART NUMBER>`` - 此文件映射到使用 VFS 驱动程序打开的 UART 中。UART 编号是 UART 外设的编号。
234+
* ``/dev/null`` - 此文件丢弃所有写入的数据,并在读取时返回 EOF。启用 :ref:`CONFIG_VFS_INITIALIZE_DEV_NULL` 会自动创建此文件。
235+
* ``/dev/console`` - 此文件连接到在 menuconfig 中由 :ref:`CONFIG_ESP_CONSOLE_UART` 和 :ref:`CONFIG_ESP_CONSOLE_SECONDARY` 指定的主输出和次输出。更多信息请参考 :doc:`../../api-guides/stdio`。
236+
216237

217238
应用示例
218239
----------------
@@ -223,6 +244,7 @@ IDF 定义了多个可供应用程序使用的 VFS 设备。这些设备包括
223244

224245
- :example:`storage/semihost_vfs` 演示了如何使用半托管 VFS 驱动程序,包括注册主机目录、将 UART 的 stdout 重定向到主机上的文件,并读取和打印文本文件的内容。
225246

247+
226248
API 参考
227249
-------------
228250

0 commit comments

Comments
 (0)