Merge branch 'update/api-reference/provisioning_and_api-reference_storage' into 'master'

docs: update format issues for EN and CN files under api-reference/provisioning and api-reference/storage

Closes DOC-5806

See merge request espressif/esp-idf!24867
pull/12000/head
Cai Xin Ying 2023-07-25 10:03:49 +08:00
commit 5f68437c2f
18 zmienionych plików z 126 dodań i 118 usunięć

Wyświetl plik

@ -239,7 +239,7 @@ After session establishment, the client can also request Wi-Fi scan results from
* ``passive`` (input) - If true, the scan is started in passive mode, which may be slower, instead of active mode.
* ``group_channels`` (input) - This specifies whether to scan all channels in one go when zero, or perform scanning of channels in groups, with 120 ms delay between scanning of consecutive groups, and the value of this parameter sets the number of channels in each group. This is useful when transport mode is SoftAP, where scanning all channels in one go may not give the Wi-Fi driver enough time to send out beacons, and hence may cause disconnection with any connected stations. When scanning in groups, the manager waits for at least 120 ms after completing the scan on a group of channels, and thus allows the driver to send out the beacons. For example, given that the total number of Wi-Fi channels is 14, then setting ``group_channels`` to 3 creates 5 groups, with each group having 3 channels, except the last one which has 14 % 3 = 2 channels. So, when the scan is started, the first 3 channels will be scanned, followed by a 120 ms delay, and then the next 3 channels, and so on, until all the 14 channels have been scanned.One may need to adjust this parameter as having only a few channels in a group may increase the overall scan time, while having too many may again cause disconnection. Usually, a value of 4 should work for most cases. Note that for any other mode of transport, e.g. Bluetooth LE, this can be safely set to 0, and hence achieve the shortest overall scanning time.
* ``group_channels`` (input) - This specifies whether to scan all channels in one go when zero, or perform scanning of channels in groups, with 120 ms delay between scanning of consecutive groups, and the value of this parameter sets the number of channels in each group. This is useful when transport mode is SoftAP, where scanning all channels in one go may not give the Wi-Fi driver enough time to send out beacons, and hence may cause disconnection with any connected stations. When scanning in groups, the manager waits for at least 120 ms after completing the scan on a group of channels, and thus allows the driver to send out the beacons. For example, given that the total number of Wi-Fi channels is 14, then setting ``group_channels`` to 3 creates 5 groups, with each group having 3 channels, except the last one which has 14 % 3 = 2 channels. So, when the scan is started, the first 3 channels will be scanned, followed by a 120 ms delay, and then the next 3 channels, and so on, until all the 14 channels have been scanned.One may need to adjust this parameter as having only a few channels in a group may increase the overall scan time, while having too many may again cause disconnection. Usually, a value of 4 should work for most cases. Note that for any other mode of transport, e.g., Bluetooth LE, this can be safely set to 0, and hence achieve the shortest overall scanning time.
* ``period_ms`` (input) - The scan parameter specifying how long to wait on each channel.
@ -283,7 +283,7 @@ One can also choose to call :cpp:func:`wifi_prov_mgr_endpoint_unregister()` to m
When/How to Stop the Provisioning Service?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The default behavior is that once the device successfully connects using the Wi-Fi credentials set by the ``apply_config`` command, the provisioning service stops, and Bluetooth LE or SoftAP turns off, automatically after responding to the next ``get_status`` command. If ``get_status`` command is not received by the device, the service stops after a 30s timeout.
The default behavior is that once the device successfully connects using the Wi-Fi credentials set by the ``apply_config`` command, the provisioning service stops, and Bluetooth LE or SoftAP turns off, automatically after responding to the next ``get_status`` command. If ``get_status`` command is not received by the device, the service stops after a 30 s timeout.
On the other hand, if device is not able to connect using the provided Wi-Fi credentials, due to incorrect SSID or passphrase, the service keeps running, and ``get_status`` keeps responding with disconnected status and reason for disconnection. Any further attempts to provide another set of Wi-Fi credentials, are to be rejected. These credentials are preserved, unless the provisioning service is force started, or NVS erased.

Wyświetl plik

@ -22,7 +22,7 @@ Most applications use the following workflow when working with ``esp_vfs_fat_``
1. Call :cpp:func:`esp_vfs_fat_register` to specify:
- Path prefix where to mount the filesystem (e.g., ``"/sdcard"``, ``"/spiflash"``)
- FatFs drive number
- A variable which will receive the pointer to the ``FATFS`` structure
- A variable which receives the pointer to the ``FATFS`` structure
2. Call :cpp:func:`ff_diskio_register` to register the disk I/O driver for the drive number used in Step 1.
@ -30,7 +30,7 @@ Most applications use the following workflow when working with ``esp_vfs_fat_``
4. Call the C standard library and POSIX API functions to perform such actions on files as open, read, write, erase, copy, etc. Use paths starting with the path prefix passed to :cpp:func:`esp_vfs_register` (for example, ``"/sdcard/hello.txt"``). The filesystem uses `8.3 filenames <https://en.wikipedia.org/wiki/8.3_filename>`_ format (SFN) by default. If you need to use long filenames (LFN), enable the :ref:`CONFIG_FATFS_LONG_FILENAMES` option. More details on the FatFs filenames are available `here <http://elm-chan.org/fsw/ff/doc/filename.html>`_.
5. Optionally, by enabling the option :ref:`CONFIG_FATFS_USE_FASTSEEK`, you can use the POSIX lseek function to perform it faster. The fast seek will not work for files in write mode, so to take advantage of fast seek, you should open (or close and then reopen) the file in read-only mode.
5. Optionally, by enabling the option :ref:`CONFIG_FATFS_USE_FASTSEEK`, you can use the POSIX lseek function to perform it faster. The fast seek does not work for files in write mode, so to take advantage of fast seek, you should open (or close and then reopen) the file in read-only mode.
6. Optionally, call the FatFs library functions directly. In this case, use paths without a VFS prefix (for example, ``"/hello.txt"``).
@ -66,7 +66,7 @@ The convenience function :cpp:func:`esp_vfs_fat_sdmmc_unmount` unmounts the file
Using FatFs with VFS in Read-Only Mode
--------------------------------------
The header file :component_file:`fatfs/vfs/esp_vfs_fat.h` also defines the convenience functions :cpp:func:`esp_vfs_fat_spiflash_mount_ro` and :cpp:func:`esp_vfs_fat_spiflash_unmount_ro`. These functions perform Steps 1-3 and 7-9 respectively for read-only FAT partitions. These are particularly helpful for data partitions written only once during factory provisioning which will not be changed by production application throughout the lifetime of the hardware.
The header file :component_file:`fatfs/vfs/esp_vfs_fat.h` also defines the convenience functions :cpp:func:`esp_vfs_fat_spiflash_mount_ro` and :cpp:func:`esp_vfs_fat_spiflash_unmount_ro`. These functions perform Steps 1-3 and 7-9 respectively for read-only FAT partitions. These are particularly helpful for data partitions written only once during factory provisioning, which will not be changed by production application throughout the lifetime of the hardware.
.. doxygenfunction:: esp_vfs_fat_spiflash_mount_ro
.. doxygenfunction:: esp_vfs_fat_spiflash_unmount_ro
@ -92,11 +92,11 @@ These APIs provide implementation of disk I/O functions for SD/MMC cards and can
FatFs Partition Generator
-------------------------
We provide a partition generator for FatFs (:component_file:`wl_fatfsgen.py<fatfs/wl_fatfsgen.py>`) which is integrated into the build system and could be easily used in the user project.
We provide a partition generator for FatFs (:component_file:`wl_fatfsgen.py <fatfs/wl_fatfsgen.py>`) which is integrated into the build system and could be easily used in the user project.
The tool is used to create filesystem images on a host and populate it with content of the specified host folder.
The script is based on the partition generator (:component_file:`fatfsgen.py<fatfs/fatfsgen.py>`). Apart from generating partition, it can also initialize wear levelling.
The script is based on the partition generator (:component_file:`fatfsgen.py <fatfs/fatfsgen.py>`). Apart from generating partition, it can also initialize wear levelling.
The latest version supports both short and long file names, FAT12 and FAT16. The long file names are limited to 255 characters and can contain multiple periods (``.``) characters within the filename and additional characters ``+``, ``,``, ``;``, ``=``, ``[`` and ``]``.
@ -120,7 +120,7 @@ If you decide for any reason to use ``fatfs_create_rawflash_image`` (without wea
The arguments of the function are as follows:
1. partition - the name of the partition as defined in the partition table (e.g. :example_file:`storage/fatfsgen/partitions_example.csv`).
1. partition - the name of the partition as defined in the partition table (e.g., :example_file:`storage/fatfsgen/partitions_example.csv`).
2. base_dir - the directory that will be encoded to FatFs partition and optionally flashed into the device. Beware that you have to specify the suitable size of the partition in the partition table.
@ -141,9 +141,9 @@ For an example, see :example:`storage/fatfsgen`.
FatFs Partition Analyzer
------------------------
(:component_file:`fatfsparse.py<fatfs/fatfsparse.py>`) is a partition analyzing tool for FatFs.
(:component_file:`fatfsparse.py <fatfs/fatfsparse.py>`) is a partition analyzing tool for FatFs.
It is a reverse tool of (:component_file:`fatfsgen.py<fatfs/fatfsgen.py>`), i.e. it can generate the folder structure on the host based on the FatFs image.
It is a reverse tool of (:component_file:`fatfsgen.py <fatfs/fatfsgen.py>`), i.e., it can generate the folder structure on the host based on the FatFs image.
Usage::

Wyświetl plik

@ -5,9 +5,9 @@
Generating and Parsing FATFS on Host
====================================
This chapter is intended mainly for developers of Python tools :component_file:`fatfsgen.py<fatfs/fatfsgen.py>` and :component_file:`fatfsparse.py<fatfs/fatfsparse.py>`, and people with special interest in these tools and implementation of the FAT file system in ESP-IDF. If you are interested in using these tools, please refer to the user guide at :ref:`fatfs-partition-generator`.
This chapter is intended mainly for developers of Python tools :component_file:`fatfsgen.py <fatfs/fatfsgen.py>` and :component_file:`fatfsparse.py <fatfs/fatfsparse.py>`, and people with special interest in these tools and implementation of the FAT file system in ESP-IDF. If you are interested in using these tools, please refer to the user guide at :ref:`fatfs-partition-generator`.
The FAT file system is composed of various logical units. The units are used to store general information about the filesystem, allocations, content of files and directories, and file's metadata. The tools `fatfsgen.py` and `fatfsparse.py` implement the FAT filesystem considering all these logical units and they can also support wear levelling.
The FAT file system is composed of various logical units. The units are used to store general information about the filesystem, allocations, content of files and directories, and file's metadata. The tools ``fatfsgen.py`` and ``fatfsparse.py`` implement the FAT filesystem considering all these logical units and they can also support wear levelling.
FAT Filesystem Generator/Parser Design
@ -27,12 +27,12 @@ This is the most general entity responsible for modeling the FAT file system. It
Class WLFATFS
^^^^^^^^^^^^^
The class extends the functionality of the class **FATFS**. It implements an encapsulation of the filesystem into the wear levelling, by adding the "dummy" sector for balancing the load (a redundant sector, see the section :ref:`fafsgen-wear-levelling`), configuration sector and state sector. This class generates a binary FATFS partition with initialized wear levelling layer. For further analysis, it also provides an option to remove the wear levelling completely. The class is instantiated and invoked by the `wl_fatfsgen.py` script.
The class extends the functionality of the class **FATFS**. It implements an encapsulation of the filesystem into the wear levelling, by adding the "dummy" sector for balancing the load (a redundant sector, see the section :ref:`fafsgen-wear-levelling`), configuration sector and state sector. This class generates a binary FATFS partition with initialized wear levelling layer. For further analysis, it also provides an option to remove the wear levelling completely. The class is instantiated and invoked by the ``wl_fatfsgen.py`` script.
Class BootSectorState
^^^^^^^^^^^^^^^^^^^^^
The instance of this class contains the metadata required for building a boot sector and BPB (BIOS Parameter Block). Boot sector is basically implemented for the cross-platform compatibility, i.e. when ESP chipsets are connected with other platforms, it will always follow all the FAT filesystem standards. However, during partition generation, chip does not consume the data in this boot sector and all the other data needed, as the data is constant. In other words, changing the fields with the prefix "BS" is usually unnecessary and often does not work. If you want to add new features, please focus on fields with the prefix "BPB". Another critical role of this class is to share access to the metadata and binary image over the whole class system. Because of this, every class in the system can access this singleton.
The instance of this class contains the metadata required for building a boot sector and BPB (BIOS Parameter Block). Boot sector is basically implemented for the cross-platform compatibility, i.e., when ESP chipsets are connected with other platforms, it will always follow all the FAT filesystem standards. However, during partition generation, chip does not consume the data in this boot sector and all the other data needed, as the data is constant. In other words, changing the fields with the prefix "BS" is usually unnecessary and often does not work. If you want to add new features, please focus on fields with the prefix "BPB". Another critical role of this class is to share access to the metadata and binary image over the whole class system. Because of this, every class in the system can access this singleton.
Class FATFSState
^^^^^^^^^^^^^^^^
@ -42,11 +42,11 @@ The class **FATFSState** might be obsolete in the future, so developers could tr
Class FAT
^^^^^^^^^
FAT represents the File Allocation Table. FAT is a sequence of bytes spread over one or more sectors. The number of sectors is determined by the number of clusters and is calculated by the function `get_fat_sectors_count` in `utils.py`. The aim is to have as few sectors for one FAT as possible when you refer to every physical cluster in the file system. The FAT works as follows: For every physical cluster at ``i * some_constant`` address, FAT contains an entry at the ``i``-th location which represents next address of the clusters in the file chain. Each version of the FAT file system uses a different size for FAT entries. FAT12 uses 12 bits per entry, thus two entries span 3 bytes. FAT16 uses 16 bits per entry, thus one entry spans 2 bytes. FAT32 uses 32 bits per FAT entry, thus one entry spans 4 bytes. All entries are in little-endian byte order.
FAT represents the File Allocation Table. FAT is a sequence of bytes spread over one or more sectors. The number of sectors is determined by the number of clusters and is calculated by the function ``get_fat_sectors_count`` in ``utils.py``. The aim is to have as few sectors for one FAT as possible when you refer to every physical cluster in the file system. The FAT works as follows: For every physical cluster at ``i * some_constant`` address, FAT contains an entry at the ``i``-th location which represents next address of the clusters in the file chain. Each version of the FAT file system uses a different size for FAT entries. FAT12 uses 12 bits per entry, thus two entries span 3 bytes. FAT16 uses 16 bits per entry, thus one entry spans 2 bytes. FAT32 uses 32 bits per FAT entry, thus one entry spans 4 bytes. All entries are in little-endian byte order.
All zeros at the ``i``-th entry indicates that corresponding cluster is free, while all ones at the ``i``-th entry indicates that corresponding cluster is occupied and is the last cluster in the file chain. The other number at ``ith``-th entry determines the next cluster's address in the file chain. These clusters are not necessarily stored adjacent to one another in the memory but instead are often fragmented throughout the data region.
For partition generation, the file is divided into several parts to fit the cluster, and the allocated chain is usually conquest. Notice that the structure allocation of the files is a linked list. Every cluster in the file allocation chain has entry in the FAT which refers to the next cluster or the information about the last cluster in the file chain. As mentioned, FAT12 uses 12 bits per FAT entry, thus it can sets a maximum number of 4096 clusters, as with 12 bits (one and a half bytes), it can enumerate 4096 clusters at most. However, because of other overhead, FAT12 can have 4085 clusters at most. Similarly, FAT16 can have 65525 clusters at most and for FAT32 can have 268435445 clusters at most (as practically only 28 bits out of 32 bits are used to denote each FAT entry). The current implementation doesn't allow forcibly redefining the FAT filesystem with less than 4085 clusters to FAT16, even though the documentation claims it is possible. Notice that it would be meaningless to define it vice versa, i.e. to FAT12 with more than 4085 clusters (which implies clusters on higher addresses being inaccessible).
For partition generation, the file is divided into several parts to fit the cluster, and the allocated chain is usually conquest. Notice that the structure allocation of the files is a linked list. Every cluster in the file allocation chain has entry in the FAT which refers to the next cluster or the information about the last cluster in the file chain. As mentioned, FAT12 uses 12 bits per FAT entry, thus it can sets a maximum number of 4096 clusters, as with 12 bits (one and a half bytes), it can enumerate 4096 clusters at most. However, because of other overhead, FAT12 can have 4085 clusters at most. Similarly, FAT16 can have 65525 clusters at most and for FAT32 can have 268435445 clusters at most (as practically only 28 bits out of 32 bits are used to denote each FAT entry). The current implementation doesn't allow forcibly redefining the FAT filesystem with less than 4085 clusters to FAT16, even though the documentation claims it is possible. Notice that it would be meaningless to define it vice versa, i.e., to FAT12 with more than 4085 clusters (which implies clusters on higher addresses being inaccessible).
Class Cluster
^^^^^^^^^^^^^
@ -76,16 +76,16 @@ Class Entry
:align: center
:alt: Tree diagram
`fatfsgen.py`
-------------
``fatfsgen.py``
---------------
:component_file:`fatfsgen.py<fatfs/fatfsgen.py>` generates FAT file systems on the host.
:component_file:`fatfsgen.py <fatfs/fatfsgen.py>` generates FAT file systems on the host.
`fatfsgen.py` recursively traverses the given folder's directory structure and adds files and/or directories inside the binary partition. Users can set if the script generates the partition with wear levelling support, long file names support, and support for preserving the modification date and time from the original folder on the host.
``fatfsgen.py`` recursively traverses the given folder's directory structure and adds files and/or directories inside the binary partition. Users can set if the script generates the partition with wear levelling support, long file names support, and support for preserving the modification date and time from the original folder on the host.
The ``./fatfsgen.py Espressif`` command generates a simple binary partition with the default settings. Here ``Espressif`` is the local folder (containing files and/or sub-directories) from which binary image will be generated.
The ``./fatfsgen.py Espressif`` command generates a simple binary partition with the default settings. Here ``Espressif`` is the local folder (containing files and/or sub-directories) from which binary image is generated.
There exist two scripts for that purpose, :component_file:`fatfsgen.py<fatfs/fatfsgen.py>` and :component_file:`wl_fatfsgen.py<fatfs/wl_fatfsgen.py>`. The difference is that `wl_fatfsgen.py` firstly uses `fatfsgen.py` for generating the partition and then initializes wear leveling.
There exist two scripts for that purpose, :component_file:`fatfsgen.py <fatfs/fatfsgen.py>` and :component_file:`wl_fatfsgen.py <fatfs/wl_fatfsgen.py>`. The difference is that ``wl_fatfsgen.py`` firstly uses ``fatfsgen.py`` for generating the partition and then initializes wear leveling.
The script command line arguments are as follows::
@ -98,12 +98,12 @@ The script command line arguments are as follows::
--use_default_datetime - this flag forces using default dates and times (date == 0x2100, time == 0x0000), not using argument preserves the original filesystem metadata
input_directory - required argument - name of the directory being encoded to the binary fat-compatibile partition
`fatfsparse.py`
---------------
``fatfsparse.py``
-----------------
:component_file:`fatfsparse.py<fatfs/fatfsparse.py>` translates the binary image into the internal representation and generates the folder with equivalent content on the host. If user requires a parsing partition with initialized wear levelling, the fatfsparse.py will remove the wear levelling sectors using the function `remove_wl` provided by `wl_fatfsgen.py`. After the sectors are removed, parsing of the partition is the same as with no initial wear levelling.
:component_file:`fatfsparse.py <fatfs/fatfsparse.py>` translates the binary image into the internal representation and generates the folder with equivalent content on the host. If user requires a parsing partition with initialized wear levelling, the ``fatfsparse.py`` will remove the wear levelling sectors using the function ``remove_wl`` provided by ``wl_fatfsgen.py``. After the sectors are removed, parsing of the partition is the same as with no initial wear levelling.
``./fatfsparse.py fatfs_image.img`` command yields the directory with the equivalent content as the binary data image `fatfs_image.img`.
``./fatfsparse.py fatfs_image.img`` command yields the directory with the equivalent content as the binary data image ``fatfs_image.img``.
The script command line arguments are as follows::
@ -120,7 +120,7 @@ Features
FAT12/16
^^^^^^^^
The supported FAT types are FAT12 and FAT16. For smaller partitions, FAT12 is sufficient. The type is detected according to the count of clusters, and cannot be changed by the user. If there are less than 4085 clusters, the selected type is FAT12 (FAT's entries have 12 bits). For partitions with 4085 to 65526 clusters (with 4085 and 65526 excluded), the type is FAT16. Currently `fatfsgen.py` or `fatfsparse.py` cannot process filesystems with more than 65525 clusters.
The supported FAT types are FAT12 and FAT16. For smaller partitions, FAT12 is sufficient. The type is detected according to the count of clusters, and cannot be changed by the user. If there are less than 4085 clusters, the selected type is FAT12 (FAT's entries have 12 bits). For partitions with 4085 to 65526 clusters (with 4085 and 65526 excluded), the type is FAT16. Currently ``fatfsgen.py`` or ``fatfsparse.py`` cannot process filesystems with more than 65525 clusters.
.. _fafsgen-wear-levelling:
@ -145,8 +145,8 @@ When a new image with WL support is generated, the script initialises few extra
- reserved — 7x 32-bit words, set to 0
- crc32 — crc32 of all the previous fields, including reserved
Also, the state sector will be appended by 16-byte `pos update record` for every value of `pos`. Thus, this record will help us to determine the position of the dummy sector.
Since `erase + write` operation of the state sector is not atomic, we may lose the data if the power is cut off between "erase" and "write". However, two copies of the state are maintained to recover the state after the power outage. On each update, both copies are updated. Thus, after power outage, we can revert the original valid state.
Also, the state sector will be appended by 16-byte ``pos update record`` for every value of ``pos``. Thus, this record will help us to determine the position of the dummy sector.
Since ``erase + write`` operation of the state sector is not atomic, we may lose the data if the power is cut off between "erase" and "write". However, two copies of the state are maintained to recover the state after the power outage. On each update, both copies are updated. Thus, after power outage, we can revert the original valid state.
- The config sector: This sector contains the information about the partition used by the WL layer.
- start_addr — start address of partition (always zero)
@ -162,10 +162,10 @@ When a new image with WL support is generated, the script initialises few extra
2. Removing Wear Levelling:
While removing WL records, we have to find the position of the dummy sector, and the original and valid orders of the partition (because traversing the dummy sector shuffles the partition). The script can remove other WL sectors from the partition. Steps to remove WL records are given below.
- Find the `pos`, position of the dummy sector, which will be determined by the number of `pos update records` in the state sector.
- Find the ``pos``, position of the dummy sector, which will be determined by the number of ``pos update records`` in the state sector.
- Create the new image by removing dummy sector and merging remaining sectors before and after dummy sector.
- Then remove the WL state sectors and config sector which are placed at the end of the partition.
- Reorder the new image to get its original order. `move_count` helps us to find the beginning of the partition. The partition will start at the position `end_of_partition - move_count`. Thus the beginning of the partition after removing WL sectors will be `partition[end_of_partition - (move_count*page_size)]`.
- Reorder the new image to get its original order. ``move_count`` helps us to find the beginning of the partition. The partition will start at the position ``end_of_partition - move_count``. Thus the beginning of the partition after removing WL sectors will be ``partition[end_of_partition - (move_count*page_size)]``.
File Names Encoding
^^^^^^^^^^^^^^^^^^^
@ -180,12 +180,12 @@ The SFN is mandatory for the implementation of file names. SFN refer to the 8.3
0x000000: 46 49 4C 45 4E 41 4D 45 45 58 54 20 18 00 00 00 FILENAMEEXT.....
0x000010: 21 00 21 00 00 00 00 00 21 00 02 00 1E 00 00 00 !.!.....!.......
The entry denotes the file with 8.3 file name ("FILENAME.EXT") __(0x00/00-0A)__ of size 0x1E = 30 bytes __(0x10/0x0C)__, with default times of modification and creation (0x0021) __(0x10/00,02 and 08)__. The relevant cluster for the file is located at __0x02 (0x10/0A)__. Please notice that a character is encoded using one byte (e.g. __0x46 == 'F'__)
The entry denotes the file with 8.3 file name ("FILENAME.EXT") __(0x00/00-0A)__ of size 0x1E = 30 bytes __(0x10/0x0C)__, with default times of modification and creation (0x0021) __(0x10/00,02 and 08)__. The relevant cluster for the file is located at __0x02 (0x10/0A)__. Please notice that a character is encoded using one byte (e.g., __0x46 == 'F'__)
Long File Names (LFN)
^^^^^^^^^^^^^^^^^^^^^
The LFN supports 255 characters excluding the trailing `NULL`. The LFN supports any character as short file names with an additional period (`.`) and the following special characters: `+ , ; = [ ]`. LFN uses UNICODE, so the character is encoded using 2 bytes.
The LFN supports 255 characters excluding the trailing ``NULL``. The LFN supports any character as short file names with an additional period (``.``) and the following special characters: ``+ , ; = [ ]``. LFN uses UNICODE, so the character is encoded using 2 bytes.
The structure of one name encoded using LFN is as follows::
@ -198,17 +198,17 @@ The structure of one name encoded using LFN is as follows::
The above example encodes a file name ``thisislongfile.txt``. The record is composed of multiple entries. The first entry contains metadata and is equivalent to the SFN entry. This entry might be final if the file name conforms to the 8.3 file name convention. In such scenarios, the SFN pattern is used. Otherwise, the generator adds various entries with the LFN structure above the SFN entry. These entries hold information about the file name and its checksum for consistency. Every LFN record can hold 13 characters (26 bytes). The file name is firstly cut into some amount of 13-character substrings and these are added above the SFN entry.
We add LFN entries in reversed order, so the first entry in the directory is the last part of the file name and the last is SFN entry. In the above example, we can see that the first entry contains text ``e.txt``, while another one contains the beginning of the name ``thisislongfil``. The first byte in LFN entries denotes an order or the sequence number (numbered from 1). To determine the first entry of the LFN, the first byte is masked with 0x40 (`first_byte =| 0x40`). The specification says that the last entry value will be ORed with 0x40 and it is the mark for the last entry. For example, when the record is the second and also the last in the LFN entry, its first byte is `0x42`.
We add LFN entries in reversed order, so the first entry in the directory is the last part of the file name and the last is SFN entry. In the above example, we can see that the first entry contains text ``e.txt``, while another one contains the beginning of the name ``thisislongfil``. The first byte in LFN entries denotes an order or the sequence number (numbered from 1). To determine the first entry of the LFN, the first byte is masked with 0x40 (``first_byte =| 0x40``). The specification says that the last entry value will be ORed with 0x40 and it is the mark for the last entry. For example, when the record is the second and also the last in the LFN entry, its first byte is ``0x42``.
The LFN entry is signed at field **DIR_Attr** with value `ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID` (see the file long_filename_utils.py). The SFN entry (possibly also within LFN) contains either `ATTR_DIRECTORY` or `ATTR_ARCHIVE` in this field for directory or file respectively.
The LFN entry is signed at field **DIR_Attr** with value ``ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID`` (see the file long_filename_utils.py). The SFN entry (possibly also within LFN) contains either ``ATTR_DIRECTORY`` or ``ATTR_ARCHIVE`` in this field for directory or file respectively.
The LFN entry is tagged at the field **DIR_NTRes** with the value `0x00`. This is a sign of the SFN entry in the LFN record, if the entry is a whole SFN record, the value is `0x18`. As you can see in the first example, the value at this field is `0x18`, because the name **"FILENAME.EXT"** fits the SFN. However, the recent example showing **"thisislongfile.txt"** has value `0x00` at field **DIR_NTRes** in the last entry, since it is a LFN. The SFN needs to be unique. For that purpose, the `fatfsgen.py` uses the first 6 characters from the file name, concatenating with `~` and with ID denoting the order of the name with the same prefix. The ID is between 0 to 127, which is the maximal amount of files with the same prefix.
The LFN entry is tagged at the field **DIR_NTRes** with the value ``0x00``. This is a sign of the SFN entry in the LFN record, if the entry is a whole SFN record, the value is ``0x18``. As you can see in the first example, the value at this field is ``0x18``, because the name **"FILENAME.EXT"** fits the SFN. However, the recent example showing **"thisislongfile.txt"** has value ``0x00`` at field **DIR_NTRes** in the last entry, since it is a LFN. The SFN needs to be unique. For that purpose, the ``fatfsgen.py`` uses the first 6 characters from the file name, concatenating with ``~`` and with ID denoting the order of the name with the same prefix. The ID is between 0 to 127, which is the maximal amount of files with the same prefix.
Calculation of the checksum is described and implemented in the `utils.py` by function `lfn_checksum`. The `fatfsparse.py` assumes that the LFN entries might not be right next to each other, but it assumes the relative order is preserved. The approach is first to find the SFN belonging to some LFN record (using **DIR_NTRes** field). From then, the script starts to search by moving upwards to the beginning of the respective sector, until it finds the last entry in the LFN record (the one with the first half byte equal to 4). The entries are distinguished by their checksums. When finished, the file name can be composed.
Calculation of the checksum is described and implemented in the ``utils.py`` by function ``lfn_checksum``. The ``fatfsparse.py`` assumes that the LFN entries might not be right next to each other, but it assumes the relative order is preserved. The approach is first to find the SFN belonging to some LFN record (using **DIR_NTRes** field). From then, the script starts to search by moving upwards to the beginning of the respective sector, until it finds the last entry in the LFN record (the one with the first half byte equal to 4). The entries are distinguished by their checksums. When finished, the file name can be composed.
Date and Time in FAT Filesystem
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The FAT filesystem protocol used by ESP-IDF does not preserve the date/time on the chips' media, so all the images extracted from the device have the same default timestamp for all the FAT-specified date-time fields (creation and the last modification timestamp as well as creation, last modification and last access dates).
There are a couple of fields in the SFN entry describing time, such as **DIR_CrtTime** and **DIR_WrtTime**. Some fields are ignored by the FAT implementation used by ESP-IDF (see the file `entry.py`). However, changes in the fields **DIR_WrtTime** and **DIR_WrtDate** are preserved in the chip. Both time and data entry are 16-bit, where the granularity of the time is 2 seconds.
There are a couple of fields in the SFN entry describing time, such as **DIR_CrtTime** and **DIR_WrtTime**. Some fields are ignored by the FAT implementation used by ESP-IDF (see the file ``entry.py``). However, changes in the fields **DIR_WrtTime** and **DIR_WrtDate** are preserved in the chip. Both time and data entry are 16-bit, where the granularity of the time is 2 seconds.

Wyświetl plik

@ -13,7 +13,8 @@ This section contains reference of the high-level storage APIs. They are based o
- :doc:`Wear Levelling <wear-levelling>` library implements a flash translation layer (FTL) suitable for SPI NOR Flash. It is used as a container for FAT partitions in Flash.
.. note::
It's suggested to use high-level APIs (``esp_partition`` or file system) instead of low-level driver APIs to access the SPI NOR Flash.
It is suggested to use high-level APIs (``esp_partition`` or file system) instead of low-level driver APIs to access the SPI NOR Flash.
Due to the restriction of NOR Flash and ESP hardware, accessing the main flash will affect the performance of the whole system. See :doc:`SPI Flash Documents </api-reference/peripherals/spi_flash/index>` to learn more about the limitations.

Wyświetl plik

@ -6,11 +6,11 @@ Overview
This guide provides an overview of the NVS Encryption feature. NVS encryption helps to achieve secure storage on the device flash memory.
Data stored in NVS partitions can be encrypted using XTS-AES in the manner similar to the one mentioned in disk encryption standard IEEE P1619. For the purpose of encryption, each entry is treated as one `sector` and relative address of the entry (w.r.t. partition-start) is fed to the encryption algorithm as `sector-number`.
Data stored in NVS partitions can be encrypted using XTS-AES in the manner similar to the one mentioned in disk encryption standard IEEE P1619. For the purpose of encryption, each entry is treated as one `sector` and relative address of the entry (w.r.t., partition-start) is fed to the encryption algorithm as `sector-number`.
.. only:: SOC_HMAC_SUPPORTED
NVS Encryption can be facilitated by enabling :ref:`CONFIG_NVS_ENCRYPTION` and :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> ``CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC`` or ``CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC`` depending on the scheme to be used.
NVS Encryption can be facilitated by enabling :ref:`CONFIG_NVS_ENCRYPTION` and :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` > ``CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC`` or ``CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC`` depending on the scheme to be used.
NVS Encryption: Flash Encryption-based Scheme
@ -49,9 +49,11 @@ The XTS encryption keys in the :ref:`nvs_encr_key_partition` can be generated in
* Then the API function automatically generates and stores the NVS keys in that partition by making use of the :cpp:func:`nvs_flash_generate_keys` API function provided by :component_file:`nvs_flash/include/nvs_flash.h`. New keys are generated and stored only when the respective key partition is empty. The same key partition can then be used to read the security configurations for initializing a custom encrypted NVS partition with help of :cpp:func:`nvs_flash_secure_init_partition`.
* The API functions :cpp:func:`nvs_flash_secure_init` and :cpp:func:`nvs_flash_secure_init_partition` do not generate the keys internally. When these API functions are used for initializing encrypted NVS partitions, the keys can be generated after startup using the :cpp:func:`nvs_flash_generate_keys` API function provided by ``nvs_flash.h``. The API function will then write those keys onto the key-partition in encrypted form.
* The API functions :cpp:func:`nvs_flash_secure_init` and :cpp:func:`nvs_flash_secure_init_partition` do not generate the keys internally. When these API functions are used for initializing encrypted NVS partitions, the keys can be generated after startup using the :cpp:func:`nvs_flash_generate_keys` API function provided by ``nvs_flash.h``. The API function then writes those keys onto the key-partition in encrypted form.
.. note:: Please note that ``nvs_keys`` partition must be completely erased before you start the application in this approach. Otherwise the application may generate :c:macro:`ESP_ERR_NVS_CORRUPT_KEY_PART` error code assuming that ``nvs_keys`` partition is not empty and contains malformatted data. You can use the following command for this:
.. note::
Please note that ``nvs_keys`` partition must be completely erased before you start the application in this approach. Otherwise the application may generate :c:macro:`ESP_ERR_NVS_CORRUPT_KEY_PART` error code assuming that ``nvs_keys`` partition is not empty and contains malformatted data. You can use the following command for this:
::
parttool.py --port PORT --partition-table-file=PARTITION_TABLE_FILE --partition-table-offset PARTITION_TABLE_OFFSET erase_partition --partition-type=data --partition-subtype=nvs_keys
@ -81,7 +83,7 @@ It is possible for an application to use different keys for different NVS partit
.. only:: SOC_HMAC_SUPPORTED
NVS Encryption: HMAC peripheral-based Scheme
NVS Encryption: HMAC Peripheral-Based Scheme
--------------------------------------------
In this scheme, the XTS keys required for NVS encryption are derived from an HMAC key programmed in eFuse with the purpose :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`. Since the encryption keys are derived at runtime, they are not stored anywhere in the flash. Thus, this feature does not require a separate :ref:`nvs_encr_key_partition`.
@ -92,13 +94,13 @@ It is possible for an application to use different keys for different NVS partit
.. important::
Please take note that this scheme will use one eFuse block for storing the HMAC key required for deriving the encryption keys.
Please take note that this scheme uses one eFuse block for storing the HMAC key required for deriving the encryption keys.
- When NVS encryption is enabled, the :cpp:func:`nvs_flash_init` API function can be used to initialize the encrypted default NVS partition. The API function first checks whether an HMAC key is present at :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`.
.. note::
The valid range for the config :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` is from ``0`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY0`) to ``5`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY5`). By default, the config is set to ``6`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY_MAX`), which will have to configured before building the user application.
The valid range for the config :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` is from ``0`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY0`) to ``5`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY5`). By default, the config is set to ``6`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY_MAX`), which have to be configured before building the user application.
- If no key is found, a key is generated internally and stored at the eFuse block specified at :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`.
- If a key is found with the purpose :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`, the same is used for the derivation of the XTS encryption keys.
@ -190,7 +192,7 @@ The component :component:`nvs_sec_provider` stores all the implementation-specif
.. only:: SOC_HMAC_SUPPORTED
This component offers factory functions with which a particular security scheme can be registered without having to worry about the APIs to generate and read the encryption keys (e.g. :cpp:func:`nvs_sec_provider_register_hmac`). Refer to the :example:`security/nvs_encryption_hmac` example for API usage.
This component offers factory functions with which a particular security scheme can be registered without having to worry about the APIs to generate and read the encryption keys (e.g., :cpp:func:`nvs_sec_provider_register_hmac`). Refer to the :example:`security/nvs_encryption_hmac` example for API usage.
API Reference

Wyświetl plik

@ -1,4 +1,4 @@
Non-volatile Storage Library
Non-Volatile Storage Library
============================
:link_to_translation:`zh_CN:[中文]`
@ -60,7 +60,8 @@ There are the following functions available:
- :cpp:func:`nvs_entry_info` returns information about each key-value pair
In general, all iterators obtained via :cpp:func:`nvs_entry_find` have to be released using :cpp:func:`nvs_release_iterator`, which also tolerates ``NULL`` iterators.
:cpp:func:`nvs_entry_find` and :cpp:func:`nvs_entry_next` will set the given iterator to ``NULL`` or a valid iterator in all cases except a parameter error occured (i.e., return ``ESP_ERR_NVS_NOT_FOUND``). In case of a parameter error, the given iterator will not be modified. Hence, it is best practice to initialize the iterator to ``NULL`` before calling :cpp:func:`nvs_entry_find` to avoid complicated error checking before releasing the iterator.
:cpp:func:`nvs_entry_find` and :cpp:func:`nvs_entry_next` set the given iterator to ``NULL`` or a valid iterator in all cases except a parameter error occured (i.e., return ``ESP_ERR_NVS_NOT_FOUND``). In case of a parameter error, the given iterator will not be modified. Hence, it is best practice to initialize the iterator to ``NULL`` before calling :cpp:func:`nvs_entry_find` to avoid complicated error checking before releasing the iterator.
Security, Tampering, and Robustness
@ -102,7 +103,7 @@ You can find code examples in the :example:`storage` directory of ESP-IDF exampl
The value checked in this example holds the number of the {IDF_TARGET_NAME} module restarts. The value's function as a counter is only possible due to its storing in NVS.
The example also shows how to check if a read / write operation was successful, or if a certain value has not been initialized in NVS. The diagnostic procedure is provided in plain text to help you track the program flow and capture any issues on the way.
The example also shows how to check if a read/write operation was successful, or if a certain value has not been initialized in NVS. The diagnostic procedure is provided in plain text to help you track the program flow and capture any issues on the way.
:example:`storage/nvs_rw_blob`
@ -111,7 +112,7 @@ You can find code examples in the :example:`storage` directory of ESP-IDF exampl
* value - tracks the number of the {IDF_TARGET_NAME} module soft and hard restarts.
* blob - contains a table with module run times. The table is read from NVS to dynamically allocated RAM. A new run time is added to the table on each manually triggered soft restart, and then the added run time is written to NVS. Triggering is done by pulling down GPIO0.
The example also shows how to implement the diagnostic procedure to check if the read / write operation was successful.
The example also shows how to implement the diagnostic procedure to check if the read/write operation was successful.
:example:`storage/nvs_rw_value_cxx`
@ -144,7 +145,7 @@ Erasing
Non-erased key-value pairs are being moved into another page so that the current page can be erased. This is a transient state, i.e., page should never stay in this state at the time when any API call returns. In case of a sudden power off, the move-and-erase process will be completed upon the next power-on.
Corrupted
Page header contains invalid data, and further parsing of page data was canceled. Any items previously written into this page will not be accessible. The corresponding flash sector will not be erased immediately and will be kept along with sectors in *uninitialized* state for later use. This may be useful for debugging.
Page header contains invalid data, and further parsing of page data was canceled. Any items previously written into this page will not be accessible. The corresponding flash sector will not be erased immediately and will be kept along with sectors in **uninitialized** state for later use. This may be useful for debugging.
Mapping from flash sectors to logical pages does not have any particular order. The library will inspect sequence numbers of pages found in each flash sector and organize pages in a list based on these numbers.
@ -281,7 +282,7 @@ Data
- CRC32
(Only for strings and blobs.) Checksum calculated over all bytes of data.
Variable length values (strings and blobs) are written into subsequent entries, 32 bytes per entry. The `Span` field of the first entry indicates how many entries are used.
Variable length values (strings and blobs) are written into subsequent entries, 32 bytes per entry. The ``Span`` field of the first entry indicates how many entries are used.
Namespaces
@ -305,7 +306,7 @@ As mentioned above, each key-value pair belongs to one of the namespaces. Namesp
Item Hash List
^^^^^^^^^^^^^^
To reduce the number of reads from flash memory, each member of the Page class maintains a list of pairs: item index; item hash. This list makes searches much quicker. Instead of iterating over all entries, reading them from flash one at a time, `Page::findItem` first performs a search for the item hash in the hash list. This gives the item index within the page if such an item exists. Due to a hash collision, it is possible that a different item will be found. This is handled by falling back to iteration over items in flash.
To reduce the number of reads from flash memory, each member of the Page class maintains a list of pairs: item index; item hash. This list makes searches much quicker. Instead of iterating over all entries, reading them from flash one at a time, `Page::findItem` first performs a search for the item hash in the hash list. This gives the item index within the page if such an item exists. Due to a hash collision, it is possible that a different item is found. This is handled by falling back to iteration over items in flash.
Each node in the hash list contains a 24-bit hash and 8-bit item index. Hash is calculated based on item namespace, key name, and ChunkIndex. CRC32 is used for calculation; the result is truncated to 24 bits. To reduce the overhead for storing 32-bit entries in a linked list, the list is implemented as a double-linked list of arrays. Each array holds 29 entries, for the total size of 128 bytes, together with linked list pointers and a 32-bit count field. The minimum amount of extra RAM usage per page is therefore 128 bytes; maximum is 640 bytes.

Wyświetl plik

@ -36,13 +36,13 @@ An example which combines the SDMMC driver with the FATFS library is provided in
.. only:: SOC_SDMMC_HOST_SUPPORTED
Protocol layer API
Protocol Layer API
------------------
The protocol layer is given the :cpp:class:`sdmmc_host_t` structure. This structure describes the SD/MMC host driver, lists its capabilities, and provides pointers to functions of the driver. The protocol layer stores card-specific information in the :cpp:class:`sdmmc_card_t` structure. When sending commands to the SD/MMC host driver, the protocol layer uses the :cpp:class:`sdmmc_command_t` structure to describe the command, arguments, expected return values, and data to transfer if there is any.
Using API with SD memory cards
Using API with SD Memory Cards
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. To initialize the host, call the host driver functions, e.g., :cpp:func:`sdmmc_host_init`, :cpp:func:`sdmmc_host_init_slot`.
@ -51,7 +51,7 @@ An example which combines the SDMMC driver with the FATFS library is provided in
4. If the card is not used anymore, call the host driver function - e.g., :cpp:func:`sdmmc_host_deinit` - to disable the host peripheral and free the resources allocated by the driver.
Using API with eMMC chips
Using API with eMMC Chips
^^^^^^^^^^^^^^^^^^^^^^^^^
From the protocol layer's perspective, eMMC memory chips behave exactly like SD memory cards. Even though eMMCs are chips and do not have a card form factor, the terminology for SD cards can still be applied to eMMC due to the similarity of the protocol (`sdmmc_card_t`, `sdmmc_card_init`). Note that eMMC chips cannot be used over SPI, which makes them incompatible with the SD SPI host driver.
@ -59,7 +59,7 @@ An example which combines the SDMMC driver with the FATFS library is provided in
To initialize eMMC memory and perform read/write operations, follow the steps listed for SD cards in the previous section.
Using API with SDIO cards
Using API with SDIO Cards
^^^^^^^^^^^^^^^^^^^^^^^^^
Initialization and the probing process are the same as with SD memory cards. The only difference is in data transfer commands in SDIO mode.
@ -99,13 +99,13 @@ An example which combines the SDMMC driver with the FATFS library is provided in
There is a component ESSL (ESP Serial Slave Link) to use if you are communicating with an ESP32 SDIO slave. See :doc:`/api-reference/protocols/esp_serial_slave_link` and example :example:`peripherals/sdio/host`.
Combo (memory + IO) cards
Combo (Memory + IO) Cards
^^^^^^^^^^^^^^^^^^^^^^^^^
The driver does not support SD combo cards. Combo cards are treated as IO cards.
Thread safety
Thread Safety
^^^^^^^^^^^^^
Most applications need to use the protocol layer only in one task. For this reason, the protocol layer does not implement any kind of locking on the :cpp:class:`sdmmc_card_t` structure, or when accessing SDMMC or SD SPI host drivers. Such locking is usually implemented on a higher layer, e.g., in the filesystem driver.

Wyświetl plik

@ -15,15 +15,15 @@ Notes
- It is not a real-time stack. One write operation might take much longer than another.
- For now, it does not detect or handle bad blocks.
- SPIFFS is able to reliably utilize only around 75% of assigned partition space.
- When the filesystem is running out of space, the garbage collector is trying to find free space by scanning the filesystem multiple times, which can take up to several seconds per write function call, depending on required space. This is caused by the SPIFFS design and the issue has been reported multiple times (e.g. `here <https://github.com/espressif/esp-idf/issues/1737>`_) and in the official `SPIFFS github repository <https://github.com/pellepl/spiffs/issues/>`_. The issue can be partially mitigated by the `SPIFFS configuration <https://github.com/pellepl/spiffs/wiki/Configure-spiffs>`_.
- When the filesystem is running out of space, the garbage collector is trying to find free space by scanning the filesystem multiple times, which can take up to several seconds per write function call, depending on required space. This is caused by the SPIFFS design and the issue has been reported multiple times (e.g., `here <https://github.com/espressif/esp-idf/issues/1737>`_) and in the official `SPIFFS github repository <https://github.com/pellepl/spiffs/issues/>`_. The issue can be partially mitigated by the `SPIFFS configuration <https://github.com/pellepl/spiffs/wiki/Configure-spiffs>`_.
- Deleting a file does not always remove the whole file, which leaves unusable sections throughout the filesystem.
- When the chip experiences a power loss during a file system operation it could result in SPIFFS corruption. However the file system still might be recovered via ``esp_spiffs_check`` function. More details in the official SPIFFS `FAQ <https://github.com/pellepl/spiffs/wiki/FAQ>`_.
Tools
-----
spiffsgen.py
^^^^^^^^^^^^
``spiffsgen.py``
^^^^^^^^^^^^^^^^
:component_file:`spiffsgen.py<spiffs/spiffsgen.py>` is a write-only Python SPIFFS implementation used to create filesystem images from the contents of a host folder. To use ``spiffsgen.py``, open Terminal and run::
@ -47,9 +47,9 @@ Aside from invoking the ``spiffsgen.py`` standalone by manually running it from
spiffs_create_partition_image(<partition> <base_dir> [FLASH_IN_PROJECT] [DEPENDS dep dep dep...])
This is more convenient as the build configuration is automatically passed to the tool, ensuring that the generated image is valid for that build. An example of this is while the *image_size* is required for the standalone invocation, only the *partition* name is required when using ``spiffs_create_partition_image`` -- the image size is automatically obtained from the project's partition table.
This is more convenient as the build configuration is automatically passed to the tool, ensuring that the generated image is valid for that build. An example of this is while the **image_size** is required for the standalone invocation, only the **partition** name is required when using ``spiffs_create_partition_image`` -- the image size is automatically obtained from the project's partition table.
``spiffs_create_partition_image`` must be called from one of the component CMakeLists.txt files.
``spiffs_create_partition_image`` must be called from one of the component ``CMakeLists.txt`` files.
Optionally, users can opt to have the image automatically flashed together with the app binaries, partition tables, etc. on ``idf.py flash`` by specifying ``FLASH_IN_PROJECT``. For example::
@ -65,8 +65,8 @@ There are cases where the contents of the base directory itself is generated at
For an example, see :example:`storage/spiffsgen`.
mkspiffs
^^^^^^^^
``mkspiffs``
^^^^^^^^^^^^
Another tool for creating SPIFFS partition images is `mkspiffs <https://github.com/igrr/mkspiffs>`_. Similar to ``spiffsgen.py``, it can be used to create an image from a given folder and then flash that image using ``esptool.py``
@ -85,7 +85,7 @@ To flash the image onto {IDF_TARGET_NAME} at offset 0x110000, run::
python esptool.py --chip {IDF_TARGET_PATH_NAME} --port [port] --baud [baud] write_flash -z 0x110000 spiffs.bin
Notes on which SPIFFS tool to use
Notes on Which SPIFFS Tool to Use
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The two tools presented above offer very similar functionality. However, there are reasons to prefer one over the other, depending on the use case.
@ -100,7 +100,7 @@ Use ``mkspiffs`` in the following cases:
1. If you need to unpack SPIFFS images in addition to image generation. For now, it is not possible with ``spiffsgen.py``.
2. If you have an environment where a Python interpreter is not available, but a host compiler is available. Otherwise, a pre-compiled ``mkspiffs`` binary can do the job. However, there is no build system integration for ``mkspiffs`` and the user has to do the corresponding work: compiling ``mkspiffs`` during build (if a pre-compiled binary is not used), creating build rules/targets for the output files, passing proper parameters to the tool, etc.
See also
See Also
--------
- :doc:`Partition Table documentation <../../api-guides/partition-tables>`

Wyświetl plik

@ -1,4 +1,4 @@
Virtual filesystem component
Virtual Filesystem Component
============================
:link_to_translation:`zh_CN:[中文]`
@ -10,10 +10,10 @@ Virtual filesystem (VFS) component provides a unified interface for drivers whic
This component allows C library functions, such as fopen and fprintf, to work with FS drivers. At a high level, each FS driver is associated with some path prefix. When one of C library functions needs to open a file, the VFS component searches for the FS driver associated with the file path and forwards the call to that driver. VFS also forwards read, write, and other calls for the given file to the same FS driver.
For example, one can register a FAT filesystem driver with the ``/fat`` prefix and call ``fopen("/fat/file.txt", "w")``. The VFS component will then call the function ``open`` of the FAT driver and pass the argument ``/file.txt`` to it together with appropriate mode flags. All subsequent calls to C library functions for the returned ``FILE*`` stream will also be forwarded to the FAT driver.
For example, one can register a FAT filesystem driver with the ``/fat`` prefix and call ``fopen("/fat/file.txt", "w")``. Then the VFS component calls the function ``open`` of the FAT driver and pass the argument ``/file.txt`` to it together with appropriate mode flags. All subsequent calls to C library functions for the returned ``FILE*`` stream will also be forwarded to the FAT driver.
FS registration
FS Registration
---------------
To register an FS driver, an application needs to define an instance of the :cpp:type:`esp_vfs_t` structure and populate it with function pointers to FS APIs:
@ -65,7 +65,7 @@ Case 2: API functions are declared with an extra context pointer (the FS driver
myfs_t* myfs_inst2 = myfs_mount(partition2->offset, partition2->size);
ESP_ERROR_CHECK(esp_vfs_register("/data2", &myfs, myfs_inst2));
Synchronous input/output multiplexing
Synchronous Input/Output Multiplexing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Synchronous input/output multiplexing by :cpp:func:`select` is supported in the VFS component. The implementation works in the following way.
@ -82,7 +82,7 @@ Synchronous input/output multiplexing by :cpp:func:`select` is supported in the
6. The :cpp:func:`select` call ends and returns the appropriate results.
Non-socket VFS drivers
Non-Socket VFS Drivers
""""""""""""""""""""""
If you want to use :cpp:func:`select` with a file descriptor belonging to a non-socket VFS driver, then you need to register the driver with functions :cpp:func:`start_select` and :cpp:func:`end_select` similarly to the following example:
@ -101,6 +101,7 @@ If you want to use :cpp:func:`select` with a file descriptor belonging to a non-
:cpp:func:`end_select` is called to stop/deinitialize/free the environment which was setup by :cpp:func:`start_select`.
.. note::
:cpp:func:`end_select` might be called without a previous :cpp:func:`start_select` call in some rare circumstances. :cpp:func:`end_select` should fail gracefully if this is the case (i.e., should not crash but return an error instead).
Please refer to the reference implementation for the UART peripheral in :component_file:`vfs/vfs_uart.c` and most particularly to the functions :cpp:func:`esp_vfs_dev_uart_register`, :cpp:func:`uart_start_select`, and :cpp:func:`uart_end_select` for more information.
@ -111,7 +112,7 @@ Please check the following examples that demonstrate the use of :cpp:func:`selec
- :example:`system/select`
Socket VFS drivers
Socket VFS Drivers
""""""""""""""""""
A socket VFS driver is using its own internal implementation of :cpp:func:`select` and non-socket VFS drivers notify it upon read/write/error conditions.
@ -131,7 +132,7 @@ A socket VFS driver needs to be registered with the following functions defined:
:cpp:func:`socket_select` is the internal implementation of :cpp:func:`select` for the socket driver. It works only with file descriptors belonging to the socket VFS.
:cpp:func:`get_socket_select_semaphore` returns the signalization object (semaphore) which will be used in non-socket drivers to stop the waiting in :cpp:func:`socket_select`.
:cpp:func:`get_socket_select_semaphore` returns the signalization object (semaphore) which is used in non-socket drivers to stop the waiting in :cpp:func:`socket_select`.
:cpp:func:`stop_socket_select` call is used to stop the waiting in :cpp:func:`socket_select` by passing the object returned by :cpp:func:`get_socket_select_semaphore`.
@ -157,7 +158,7 @@ Then:
- FS 1 will be used when opening a file called ``/data/log.txt``
- FS 2 will be used when opening a file called ``/data/static/index.html``
- Even if ``/index.html"`` does not exist in FS 2, FS 1 will *not* be searched for ``/static/index.html``.
- Even if ``/index.html"`` does not exist in FS 2, FS 1 will **not** be searched for ``/static/index.html``.
As a general rule, mount point names must start with the path separator (``/``) and must contain at least one character after path separator. However, an empty mount point name is also supported and might be used in cases when an application needs to provide a "fallback" filesystem or to override VFS functionality altogether. Such filesystem will be used if no prefix matches the path given.
@ -173,18 +174,18 @@ When opening files, the FS driver receives only relative paths to files. For exa
VFS does not impose any limit on total file path length, but it does limit the FS path prefix to ``ESP_VFS_PATH_MAX`` characters. Individual FS drivers may have their own filename length limitations.
File descriptors
File Descriptors
----------------
File descriptors are small positive integers from ``0`` to ``FD_SETSIZE - 1``, where ``FD_SETSIZE`` is defined in newlib's ``sys/types.h``. The largest file descriptors (configured by ``CONFIG_LWIP_MAX_SOCKETS``) are reserved for sockets. The VFS component contains a lookup-table called ``s_fd_table`` for mapping global file descriptors to VFS driver indexes registered in the ``s_vfs`` array.
Standard IO streams (stdin, stdout, stderr)
Standard IO Streams (stdin, stdout, stderr)
-------------------------------------------
If the menuconfig option ``UART for console output`` is not set to ``None``, then ``stdin``, ``stdout``, and ``stderr`` are configured to read from, and write to, a UART. It is possible to use UART0 or UART1 for standard IO. By default, UART0 is used with 115200 baud rate; TX pin is GPIO1; RX pin is GPIO3. These parameters can be changed in menuconfig.
Writing to ``stdout`` or ``stderr`` will send characters to the UART transmit FIFO. Reading from ``stdin`` will retrieve characters from the UART receive FIFO.
Writing to ``stdout`` or ``stderr`` sends characters to the UART transmit FIFO. Reading from ``stdin`` retrieves characters from the UART receive FIFO.
By default, VFS uses simple functions for reading from and writing to UART. Writes busy-wait until all data is put into UART FIFO, and reads are non-blocking, returning only the data present in the FIFO. Due to this non-blocking read behavior, higher level C library calls, such as ``fscanf("%d\n", &var);``, might not have desired results.
@ -193,7 +194,7 @@ Applications which use the UART driver can instruct VFS to use the driver's inte
VFS also provides an optional newline conversion feature for input and output. Internally, most applications send and receive lines terminated by the LF (''\n'') character. Different terminal programs may require different line termination, such as CR or CRLF. Applications can configure this separately for input and output either via menuconfig, or by calls to the functions ``esp_vfs_dev_uart_port_set_rx_line_endings`` and ``esp_vfs_dev_uart_port_set_tx_line_endings``.
Standard streams and FreeRTOS tasks
Standard Streams and FreeRTOS Tasks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``FILE`` objects for ``stdin``, ``stdout``, and ``stderr`` are shared between all FreeRTOS tasks, but the pointers to these objects are stored in per-task ``struct _reent``.
@ -212,7 +213,7 @@ The ``__getreent()`` function returns a per-task pointer to ``struct _reent`` in
Such a design has the following consequences:
- It is possible to set ``stdin``, ``stdout``, and ``stderr`` for any given task without affecting other tasks, e.g., by doing ``stdin = fopen("/dev/uart/1", "r")``.
- Closing default ``stdin``, ``stdout``, or ``stderr`` using ``fclose`` will close the ``FILE`` stream object, which will affect all other tasks.
- Closing default ``stdin``, ``stdout``, or ``stderr`` using ``fclose`` closes the ``FILE`` stream object, which will affect all other tasks.
- To change the default ``stdin``, ``stdout``, ``stderr`` streams for new tasks, modify ``_GLOBAL_REENT->_stdin`` (``_stdout``, ``_stderr``) before creating the task.
Event fds

Wyświetl plik

@ -1,6 +1,6 @@
.. include:: ../../../../components/wear_levelling/README.rst
See also
See Also
--------
- :doc:`FAT Filesystem <./fatfs>`
@ -11,7 +11,7 @@ Application Example
An example which combines the wear levelling driver with the FATFS library is provided in the :example:`storage/wear_levelling` directory. This example initializes the wear levelling driver, mounts FATFS partition, as well as writes and reads data from it using POSIX and C library APIs. See the :example_file:`storage/wear_levelling/README.md` file for more information.
High level API Reference
High-Level API Reference
------------------------
Header Files
@ -27,7 +27,7 @@ Functions
:members:
.. doxygenfunction:: esp_vfs_fat_spiflash_unmount_rw_wl
Mid level API Reference
Mid-Level API Reference
-----------------------
.. include-build-file:: inc/wear_levelling.inc

Wyświetl plik

@ -103,7 +103,7 @@ ESP-IDF 支持统一配网,提供可扩展的机制,支持开发者使用不
2. **应用程序层安全**
统一配网子系统支持应用层的安全方案 (`Security 1 方案`_),即通过 PoP 提供数据保护和身份验证。如果应用程序不使用传输层的安全方案,或者传输层的安全方案不满足使用场景的需求,可以使用该方案。
统一配网子系统支持应用层的安全方案 `Security 1 方案`_,即通过 PoP 提供数据保护和身份验证。如果应用程序不使用传输层的安全方案,或者传输层的安全方案不满足使用场景的需求,可以使用该方案。
设备发现
>>>>>>>>>>>>>>>>

Wyświetl plik

@ -235,27 +235,27 @@ Wi-Fi 配网
* ``scan_start`` - 启动 Wi-Fi 扫描有多个选项,具体如下:
* ``blocking`` (输入) - 如果参数为 true则命令只会在扫描完成后返回。
* ``blocking`` (输入)- 如果参数为 true则命令只会在扫描完成后返回。
* ``passive`` (输入) - 如果参数为 true则以被动模式启动扫描扫描速度可能更慢。
* ``passive`` (输入)- 如果参数为 true则以被动模式启动扫描扫描速度可能更慢。
* ``group_channels`` (输入) - 该参数用于指定是否分组扫描。如果参数为 0表示一次性扫描所有信道如果参数为非零值则表示分组扫描信道且参数值为每组中的信道数每个连续组之间有 120 毫秒的延迟。分组扫描非常适用于使用 SoftAP 的传输模式,因为一次性扫描所有信道可能会导致 Wi-Fi 驱动没有足够时间发送信标,进而导致与部分站点断连。分组扫描时,管理器每扫描完一组信道,至少会等待 120 毫秒,确保驱动程序有足够时间发送信标。例如,假设共有 14 个 Wi-Fi 信道,将 ``group_channels`` 设置为 3 则将创建 5 个分组,每个分组包含 3 个信道,最后一个分组则为 14 除以 3 余下的 2 个信道。因此,扫描开始时,首先会扫描前 3 个信道,然后等待 120 毫秒,再继续扫描后 3 个信道,以此类推,直到扫描完 14 个信道。可以根据实际情况调整此参数,因为分组中信道数量过少可能会增加整体扫描时间,而信道数量过多则可能会导致连接再次断开。大多数情况下,将参数值设置为 4 即可。请注意,对于低功耗蓝牙等其他传输模式,可以放心将该参数设置为 0从而在最短时间内完成扫描。
* ``group_channels`` (输入)- 该参数用于指定是否分组扫描。如果参数为 0表示一次性扫描所有信道如果参数为非零值则表示分组扫描信道且参数值为每组中的信道数每个连续组之间有 120 毫秒的延迟。分组扫描非常适用于使用 SoftAP 的传输模式,因为一次性扫描所有信道可能会导致 Wi-Fi 驱动没有足够时间发送信标,进而导致与部分站点断连。分组扫描时,管理器每扫描完一组信道,至少会等待 120 毫秒,确保驱动程序有足够时间发送信标。例如,假设共有 14 个 Wi-Fi 信道,将 ``group_channels`` 设置为 3 则将创建 5 个分组,每个分组包含 3 个信道,最后一个分组则为 14 除以 3 余下的 2 个信道。因此,扫描开始时,首先会扫描前 3 个信道,然后等待 120 毫秒,再继续扫描后 3 个信道,以此类推,直到扫描完 14 个信道。可以根据实际情况调整此参数,因为分组中信道数量过少可能会增加整体扫描时间,而信道数量过多则可能会导致连接再次断开。大多数情况下,将参数值设置为 4 即可。请注意,对于低功耗蓝牙等其他传输模式,可以放心将该参数设置为 0从而在最短时间内完成扫描。
* ``period_ms`` (输入) - 该扫描参数用于设置在每个信道上的等待时间。
* ``period_ms`` (输入)- 该扫描参数用于设置在每个信道上的等待时间。
* ``scan_status`` - 可以返回扫描过程的状态:
* ``scan_finished`` (输出) - 扫描完成时,该参数返回为 true。
* ``scan_finished`` (输出)- 扫描完成时,该参数返回为 true。
* ``result_count`` (输出) - 该参数返回到目前为止获取的结果总数。如果扫描仍在进行,该数字会不断更新。
* ``result_count`` (输出)- 该参数返回到目前为止获取的结果总数。如果扫描仍在进行,该数字会不断更新。
* ``scan_result`` - 用于获取扫描结果。即使扫描仍在进行,也可以调用此函数。
* ``start_index`` (输入) - 从结果列表中获取条目的起始索引位置。
* ``start_index`` (输入)- 从结果列表中获取条目的起始索引位置。
* ``count`` (输入) - 从起始索引位置获取的条目数目。
* ``count`` (输入)- 从起始索引位置获取的条目数目。
* ``entries`` (输出) - 返回条目的列表。每个条目包含 ``ssid````channel````rssi`` 信息。
* ``entries`` (输出)- 返回条目的列表。每个条目包含 ``ssid````channel````rssi`` 信息。
客户端还可以使用 ``wifi_ctrl`` 端点来控制设备的配网状态。``wifi_ctrl`` 端点支持的 protobuf 命令如下:

Wyświetl plik

@ -3,7 +3,7 @@ FAT 文件系统
:link_to_translation:`en:[English]`
ESP-IDF 使用 `FatFs <http://elm-chan.org/fsw/ff/00index_e.html>`_ 库来实现 FAT 文件系统。FatFs 库位于 ``fatfs`` 组件中,您可以直接使用,也可以借助 C 标准库和 POSIX API 通过 VFS虚拟文件系统使用 FatFs 库的大多数功能。
ESP-IDF 使用 `FatFs <http://elm-chan.org/fsw/ff/00index_e.html>`_ 库来实现 FAT 文件系统。FatFs 库位于 ``fatfs`` 组件中,支持直接使用,也可以借助 C 标准库和 POSIX API 通过 VFS虚拟文件系统使用 FatFs 库的大多数功能。
此外,我们对 FatFs 库进行了扩展,新增了支持可插拔磁盘 I/O 调度层,从而允许在运行时将 FatFs 驱动映射到物理磁盘。
@ -28,11 +28,11 @@ FatFs 与 VFS 配合使用
3. 调用 FatFs 函数 ``f_mount``,随后调用 ``f_fdisk````f_mkfs``,并使用与传递到 :cpp:func:`esp_vfs_fat_register` 相同的驱动编号挂载文件系统。请参考 `FatFs 文档 <http://elm-chan.org/fsw/ff/doc/mount.html>`_查看更多信息
4. 调用 C 标准库和 POSIX API 对路径中带有步骤 1 中所述前缀的文件(例如,``"/sdcard/hello.txt"``)执行打开、读取、写入、擦除、复制等操作。文件系统默认使用 `8.3 文件名 <https://en.wikipedia.org/wiki/8.3_filename>`_ 格式 (SFN)。若您需要使用长文件名 (LFN),启用 :ref:`CONFIG_FATFS_LONG_FILENAMES` 选项。请参考 `here <http://elm-chan.org/fsw/ff/doc/filename.html>`_查看更多信息
4. 调用 C 标准库和 POSIX API 对路径中带有步骤 1 中所述前缀的文件(例如,``"/sdcard/hello.txt"``)执行打开、读取、写入、擦除、复制等操作。文件系统默认使用 `8.3 文件名 <https://en.wikipedia.org/wiki/8.3_filename>`_ 格式 (SFN)。如需使用长文件名 (LFN),启用 :ref:`CONFIG_FATFS_LONG_FILENAMES` 选项。请参考 `here <http://elm-chan.org/fsw/ff/doc/filename.html>`_查看更多信息
5. 您可以选择启用 :ref:`CONFIG_FATFS_USE_FASTSEEK` 选项,使用 POSIX lseek 来快速执行。快速查找不适用于编辑模式下的文件,所以,使用快速查找时,应在只读模式下打开(或者关闭然后重新打开)文件;
5. 选择启用 :ref:`CONFIG_FATFS_USE_FASTSEEK` 选项,可以使用 POSIX lseek 实现快速执行。快速查找不适用于编辑模式下的文件,所以,使用快速查找时,应在只读模式下打开(或者关闭然后重新打开)文件;
6. 也可选择直接调用 FatFs 库函数,但需要使用没有 VFS 前缀的路径(例如,``"/hello.txt"``
6. 也可选择直接调用 FatFs 库函数,但需要使用没有 VFS 前缀的路径(例如,``"/hello.txt"``
7. 关闭所有打开的文件;
@ -100,7 +100,7 @@ FatFs 分区生成器
目前的最新版本支持短文件名、长文件名、FAT12 和 FAT16。长文件名的上限是 255 个字符,文件名中可以包含多个 ``.`` 字符以及其他字符,如 ``+````,````;````=````[`` and ``]`` 等。
您想进一步了解 FatFs 分区生成器或分区分析器,请查看 :doc:`Generating and parsing FAT partition on host <./fatfsgen>`
进一步了解 FatFs 分区生成器或分区分析器,请查看 :doc:`Generating and parsing FAT partition on host <./fatfsgen>`
构建系统中使用 FatFs 分区生成器
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -115,7 +115,7 @@ FatFs 分区生成器
``fatfs_create_spiflash_image`` 以及 ``fatfs_create_rawflash_image`` 必须从项目的 CMakeLists.txt 中调用。
如果决定使用 ``fatfs_create_rawflash_image`` (不支持磨损均衡),请注意它仅支持在设备中以只读模式安装。
如果决定使用 ``fatfs_create_rawflash_image`` (不支持磨损均衡),请注意它仅支持在设备中以只读模式安装。
该函数的参数如下:
@ -145,6 +145,6 @@ FatFs 分区分析器
该分析器为 FatFs 分区生成器 (:component_file:`fatfsgen.py<fatfs/fatfsgen.py>`) 的逆向工具,可以根据 FatFs 镜像在主机上生成文件夹结构。
可以使用::
可以使用::
./fatfsparse.py [-h] [--wl-layer {detect,enabled,disabled}] fatfs_image.img

Wyświetl plik

@ -13,6 +13,7 @@
- :doc:`磨损均衡 <wear-levelling>` 库实现了一个适用于 SPI NOR Flash 的 Flash 翻译层 (FTL),用于 Flash 中 FAT 分区的容器。
.. note::
建议使用高层次的 API ``esp_partition`` 或者文件系统)而非低层次驱动 API 去访问 SPI NOR Flash 。
由于 NOR Flash 和乐鑫硬件的一些限制,访问主 Flash 会影响各个系统的性能。关于这些限制的更多信息,参见 :doc:`SPI Flash Documents </api-reference/peripherals/spi_flash/index>`

Wyświetl plik

@ -53,13 +53,14 @@ NVS 迭代器
迭代器允许根据指定的分区名称、命名空间和数据类型轮询 NVS 中存储的键值对。
您可以使用以下函数,执行相关操作:
使用以下函数,执行相关操作:
- ``nvs_entry_find``:创建一个不透明句柄,用于后续调用 ``nvs_entry_next````nvs_entry_info`` 函数;
- ``nvs_entry_next``:让迭代器指向下一个键值对;
- ``nvs_entry_info``:返回每个键值对的信息。
总的来说,所有通过 :cpp:func:`nvs_entry_find` 获得的迭代器(包括 ``NULL`` 迭代器)都必须使用 :cpp:func:`nvs_release_iterator` 释放。
一般情况下,:cpp:func:`nvs_entry_find`:cpp:func:`nvs_entry_next` 会将给定的迭代器设置为 ``NULL`` 或为一个有效的迭代器。但如果出现参数错误(如返回 ``ESP_ERR_NVS_NOT_FOUND``),给定的迭代器不会被修改。因此,在调用 :cpp:func:`nvs_entry_find` 之前最好将迭代器初始化为 ``NULL``,这样可以避免在释放迭代器之前进行复杂的错误检查。
@ -102,9 +103,9 @@ ESP-IDF :example:`storage` 目录下提供了数个代码示例:
此示例中的值表示 {IDF_TARGET_NAME} 模组重启次数。NVS 中数据不会因为模组重启而丢失,因此只有将这一值存储于 NVS 中,才能起到重启次数计数器的作用。
该示例也演示了如何检测读取/写入操作是否成功,以及某个特定值是否在 NVS 中尚未初始化。诊断程序以纯文本形式提供,帮助您追踪程序流程,及时发现问题。
该示例也演示了如何检测读取/写入操作是否成功,以及某个特定值是否在 NVS 中尚未初始化。诊断程序以纯文本形式提供,有助于追踪程序流程,及时发现问题。
:example:`storage/nvs_rw_blob` 
:example:`storage/nvs_rw_blob`
演示如何读取及写入 NVS 单个整数值和 BLOB二进制大对象并在 NVS 中存储这一数值,即便 {IDF_TARGET_NAME} 模组重启也不会消失。
@ -281,7 +282,7 @@ CRC32
- CRC32
数据所有字节的校验和,该字段仅用于字符串和 BLOB 类型条目。
可变长度值(字符串和 BLOB写入后续条目每个条目 32 字节。第一个条目的 `Span` 字段将指明使用了多少条目。
可变长度值(字符串和 BLOB写入后续条目每个条目 32 字节。第一个条目的 ``Span`` 字段将指明使用了多少条目。
命名空间

Wyświetl plik

@ -72,7 +72,7 @@ ESP-IDF :example:`storage/sd_card` 目录下提供了 SDMMC 驱动与 FatFs 库
注意,驱动程序不会在 (1) I/O 使能寄存器和 Int 使能寄存器,及 (2) I/O 块大小中,设置任何位。应用程序可通过调用 :cpp:func:`sdmmc_io_write_byte` 来设置相关位。
如需卡配置或传输数据,请根据您的具体情况选择下表中的函数:
如需卡配置或传输数据,请根据具体情况选择下表函数:
.. list-table::
:widths: 55 25 20
@ -93,11 +93,11 @@ ESP-IDF :example:`storage/sd_card` 目录下提供了 SDMMC 驱动与 FatFs 库
使用 :cpp:func:`sdmmc_io_enable_int` 函数,应用程序可启用 SDIO 中断。在单线模式下使用 SDIO 时,还需要连接 D1 线来启用 SDIO 中断。
如果需要应用程序保持等待直至发生 SDIO 中断,请使用 :cpp:func:`sdmmc_io_wait_int` 函数。
如果需要应用程序保持等待直至发生 SDIO 中断,请使用 :cpp:func:`sdmmc_io_wait_int` 函数。
.. only:: esp32
如果需要与 ESP32 的 SDIO 从设备通信,请使用 ESSL 组件ESP 串行从设备链接)。请参阅 :doc:`/api-reference/protocols/esp_serial_slave_link`:example:`peripherals/sdio/host`
如果需要与 ESP32 的 SDIO 从设备通信,请使用 ESSL 组件ESP 串行从设备链接)。请参阅 :doc:`/api-reference/protocols/esp_serial_slave_link`:example:`peripherals/sdio/host`
复合卡(存储 + IO
^^^^^^^^^^^^^^^^^^^^^^^^^

Wyświetl plik

@ -22,7 +22,7 @@ SPIFFS 是一个用于 SPI NOR flash 设备的嵌入式文件系统,支持磨
工具
-----
spiffsgen.py
``spiffsgen.py``
^^^^^^^^^^^^^^^^
:component_file:`spiffsgen.py<spiffs/spiffsgen.py>`(只写)是 SPIFFS 的一种 Python 实现,可用于从主机文件夹内容生成文件系统镜像。打开终端并运行以下命令即可使用 ``spiffsgen.py``::
@ -47,9 +47,9 @@ spiffsgen.py
spiffs_create_partition_image(<partition> <base_dir> [FLASH_IN_PROJECT] [DEPENDS dep dep dep...])
在构建系统中使用 ``spiffsgen.py`` 更为方便,构建配置会自动传递给 ``spiffsgen.py`` 工具,确保生成的镜像可用于构建。比如,单独调用 ``spiffsgen.py`` 时需要用到 *image_size* 参数,但在构建系统中调用 ``spiffs_create_partition_image`` 时,仅需要 *partition* 参数,镜像大小将直接从工程分区表中获取。
在构建系统中使用 ``spiffsgen.py`` 更为方便,构建配置会自动传递给 ``spiffsgen.py`` 工具,确保生成的镜像可用于构建。比如,单独调用 ``spiffsgen.py`` 时需要用到 **image_size** 参数,但在构建系统中调用 ``spiffs_create_partition_image`` 时,仅需要 **partition** 参数,镜像大小将直接从工程分区表中获取。
使用 ``spiffs_create_partition_image``,必须从组件 CMakeLists.txt 文件调用。
使用 ``spiffs_create_partition_image``,必须从组件 ``CMakeLists.txt`` 文件调用。
用户也可以指定 ``FLASH_IN_PROJECT``,然后使用 ``idf.py flash`` 将镜像与应用程序二进制文件、分区表等一起自动烧录至设备,例如::
@ -65,8 +65,8 @@ spiffsgen.py
请参考 :example:`storage/spiffsgen`,查看示例。
mkspiffs
^^^^^^^^^^^
``mkspiffs``
^^^^^^^^^^^^
用户也可以使用 `mkspiffs <https://github.com/igrr/mkspiffs>`_ 工具创建 SPIFFS 分区镜像。与 ``spiffsgen.py`` 相似,`mkspiffs <https://github.com/igrr/mkspiffs>`_ 也可以用于从指定文件夹中生成镜像,然后使用 ``esptool.py`` 烧录镜像。

Wyświetl plik

@ -10,7 +10,7 @@
VFS 组件支持 C 库函数(如 fopen 和 fprintf 等)与文件系统 (FS) 驱动程序协同工作。在高层级,每个 FS 驱动程序均与某些路径前缀相关联。当一个 C 库函数需要打开文件时VFS 组件将搜索与该文件所在文件路径相关联的 FS 驱动程序,并将调用传递给该驱动程序。针对该文件的读取、写入等其他操作的调用也将传递给这个驱动程序。
例如,您可以使用 ``/fat`` 前缀注册 FAT 文件系统驱动,之后即可调用 ``fopen("/fat/file.txt", "w")``。之后VFS 将调用 FAT 驱动的 ``open`` 函数,并将参数 ``/file.txt`` 和合适的打开模式传递给 ``open`` 函数;后续对返回的 ``FILE*`` 数据流调用 C 库函数也同样会传递给 FAT 驱动。
例如,使用 ``/fat`` 前缀注册 FAT 文件系统驱动,之后即可调用 ``fopen("/fat/file.txt", "w")``。之后VFS 将调用 FAT 驱动的 ``open`` 函数,并将参数 ``/file.txt`` 和合适的打开模式传递给 ``open`` 函数;后续对返回的 ``FILE*`` 数据流调用 C 库函数也同样会传递给 FAT 驱动。
注册 FS 驱动程序
@ -140,7 +140,8 @@ VFS 组件支持通过 :cpp:func:`select` 进行同步输入/输出多路复用
请参考 :component_file:`lwip/port/esp32xx/vfs_lwip.c` 以了解使用 LWIP 的套接字驱动参考实现。
.. note::
如果 :cpp:func:`select` 用于套接字文件描述符,您可以禁用 :ref:`CONFIG_VFS_SUPPORT_SELECT` 选项来减少代码量,提高性能。
如果 :cpp:func:`select` 用于套接字文件描述符,可以禁用 :ref:`CONFIG_VFS_SUPPORT_SELECT` 选项来减少代码量,提高性能。
不要在 :cpp:func:`select` 调用过程中更改套接字驱动,否则会出现一些未定义行为。
路径
@ -182,13 +183,13 @@ VFS 对文件路径长度没有限制,但文件系统路径前缀受 ``ESP_VFS
标准 IO 流 (stdin, stdout, stderr)
-------------------------------------------
如果 menuconfig 中 ``UART for console output`` 选项没有设置为 ``None``,则 ``stdin````stdout````stderr`` 将默认从 UART 读取或写入。UART0 或 UART1 可用作标准 IO。默认情况下UART0 使用 115200 波特率TX 管脚为 GPIO1RX 管脚为 GPIO3。您可以在 menuconfig 中更改上述参数
如果 menuconfig 中 ``UART for console output`` 选项没有设置为 ``None``,则 ``stdin````stdout````stderr`` 将默认从 UART 读取或写入。UART0 或 UART1 可用作标准 IO。默认情况下UART0 使用 115200 波特率TX 管脚为 GPIO1RX 管脚为 GPIO3。上述参数可以在 menuconfig 中更改
``stdout````stderr`` 执行写入操作将会向 UART 发送 FIFO 发送字符,对 ``stdin`` 执行读取操作则会从 UART 接收 FIFO 中取出字符。
默认情况下VFS 使用简单的函数对 UART 进行读写操作。在所有数据放进 UART FIFO 之前,写操作将处于 busy-wait 状态,读操处于非阻塞状态,仅返回 FIFO 中已有数据。由于读操作为非阻塞,高层级 C 库函数调用(如 ``fscanf("%d\n", &var);``)可能获取不到所需结果。
如果应用程序使用 UART 驱动,则可以调用 ``esp_vfs_dev_uart_use_driver`` 函数来指导 VFS 使用驱动中断、读写阻塞功能等。您也可以调用 ``esp_vfs_dev_uart_use_nonblocking`` 来恢复非阻塞函数。
如果应用程序使用 UART 驱动,则可以调用 ``esp_vfs_dev_uart_use_driver`` 函数来指导 VFS 使用驱动中断、读写阻塞功能等也可以调用 ``esp_vfs_dev_uart_use_nonblocking`` 来恢复非阻塞函数。
VFS 还为输入和输出提供换行符转换功能(可选)。多数应用程序在程序内部发送或接收以 LF (''\n'') 结尾的行,但不同的终端程序可能需要不同的换行符,比如 CR 或 CRLF。应用程序可以通过 menuconfig 或者调用 ``esp_vfs_dev_uart_port_set_rx_line_endings````esp_vfs_dev_uart_port_set_tx_line_endings`` 为输入输出配置换行符。