mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'docs/add_cn_trans_for_mm.rst_in_api-reference_system' into 'master'
docs: Provide Chinese translation for api-reference/system/mm.rst Closes DOC-6336 See merge request espressif/esp-idf!26110
This commit is contained in:
commit
9ea6f0f4ff
@ -173,7 +173,6 @@ api-reference/system/misc_system_api.rst
|
||||
api-reference/system/bootloader_image_format.rst
|
||||
api-reference/system/inc/power_management_esp32p4.rst
|
||||
api-reference/system/heap_debug.rst
|
||||
api-reference/system/mm.rst
|
||||
api-reference/system/esp_https_ota.rst
|
||||
api-reference/system/ulp-risc-v.rst
|
||||
api-reference/system/esp_err.rst
|
||||
|
@ -1,30 +1,31 @@
|
||||
Memory Management for MMU Supported Memory
|
||||
******************************************
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
{IDF_TARGET_NAME} Memory Management Unit (MMU) is relatively simple. It can do memory address translation between physical memory addresses and virtual memory addresses. So CPU can access physical memories via virtual addresses. There are multiple types of virtual memory addresses, which have different capabilities.
|
||||
|
||||
ESP-IDF provides a memory mapping driver that manages the relation between these physical memory addresses and virtual memory addresses, so as to achieve some features such as reading from SPI Flash via a pointer.
|
||||
ESP-IDF provides a memory mapping driver that manages the relation between these physical memory addresses and virtual memory addresses, so as to achieve some features such as reading from SPI flash via a pointer.
|
||||
|
||||
Memory mapping driver is actually a capabilities-based virtual memory address allocator that allows apps to make virtual memory address allocations for different purposes. In the following chapters, we call this driver ``esp_mmap`` driver.
|
||||
Memory mapping driver is actually a capabilities-based virtual memory address allocator that allows applications to make virtual memory address allocations for different purposes. In the following chapters, we call this driver ``esp_mmap`` driver.
|
||||
|
||||
ESP-IDF also provides a memory synchronisation driver which can be used for potential memory desychronisation scenarios.
|
||||
ESP-IDF also provides a memory synchronization driver which can be used for potential memory desynchronization scenarios.
|
||||
|
||||
Physical Memory Types
|
||||
=====================
|
||||
|
||||
Memory mapping driver currently supports mapping to following physical memory types:
|
||||
Memory mapping driver currently supports mapping to following physical memory type(s):
|
||||
|
||||
.. list::
|
||||
|
||||
- SPI Flash
|
||||
:SOC_SPIRAM_SUPPORTED and not esp32: - PSRAM
|
||||
- SPI flash
|
||||
:SOC_SPIRAM_SUPPORTED and not esp32: - PSRAM
|
||||
|
||||
|
||||
Virtual Memory Capabilities
|
||||
@ -32,22 +33,22 @@ Virtual Memory Capabilities
|
||||
|
||||
.. list::
|
||||
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_EXEC`. This capability indicates that the virtual memory address has the execute permission. Note this permission scope is within the MMU hardware.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_READ`. This capability indicates that the virtual memory address has the read permission. Note this permission scope is within the MMU hardware.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_WRITE`. This capability indicates that the virtual memory address has the write permission. Note this permission scope is within the MMU hardware.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_32BIT`. This capability indicates that the virtual memory address allows for 32 bits or multiples of 32 bits access.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_8BIT`. This capability indicates that the virtual memory address allows for 8 bits or multiples of 8 bits access.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_EXEC`: This capability indicates that the virtual memory address has the execute permission. Note this permission scope is within the MMU hardware.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_READ`: This capability indicates that the virtual memory address has the read permission. Note this permission scope is within the MMU hardware.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_WRITE`: This capability indicates that the virtual memory address has the write permission. Note this permission scope is within the MMU hardware.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_32BIT`: This capability indicates that the virtual memory address allows for 32 bits or multiples of 32 bits access.
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_8BIT`: This capability indicates that the virtual memory address allows for 8 bits or multiples of 8 bits access.
|
||||
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
|
||||
8 MB external memory addresses (from 0x40400000 to 0x40C00000) which have the :cpp:enumerator:`MMU_MEM_CAP_EXEC` and :cpp:enumerator:`MMU_MEM_CAP_READ` capabilities are not avaiable for users to allocate, due to hardware limitations.
|
||||
8 MB external memory addresses (from 0x40400000 to 0x40C00000) which have the :cpp:enumerator:`MMU_MEM_CAP_EXEC` and :cpp:enumerator:`MMU_MEM_CAP_READ` capabilities are not available for users to allocate, due to hardware limitations.
|
||||
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
4 MB external memory addresses (from 0x40400000 to 0x40800000) which have the :cpp:enumerator:`MMU_MEM_CAP_EXEC` and :cpp:enumerator:`MMU_MEM_CAP_READ` capabilities are not avaiable for users to allocate, due to hardware limitations.
|
||||
4 MB external memory addresses (from 0x40400000 to 0x40800000) which have the :cpp:enumerator:`MMU_MEM_CAP_EXEC` and :cpp:enumerator:`MMU_MEM_CAP_READ` capabilities are not avaiable for users to allocate, due to hardware limitations.
|
||||
|
||||
|
||||
You can call :cpp:func:`esp_mmu_map_get_max_consecutive_free_block_size` to know the largest consecutive mappable block size with certain capabilities.
|
||||
@ -67,15 +68,16 @@ Terminology
|
||||
The virtual memory pool is made up with one or multiple virtual memory regions, see below figure:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/mem_pool.png
|
||||
:scale: 100 %
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
- A virtual memory pool stands for the whole virtual address range that can be mapped to physical memory
|
||||
- A virtual memory region is a range of virtual address with same attributes
|
||||
|
||||
- A virtual memory pool stands for the whole virtual address range that can be mapped to physical memory.
|
||||
- A virtual memory region is a range of virtual address with same attributes.
|
||||
- A virtual memory block is a piece of virtual address range that is dynamically mapped.
|
||||
- A slot is the virtual address range between two virtual memory blocks.
|
||||
- A physical memory block is a piece of physical address range that is to-be-mapped or already mapped to a virtual memory block.
|
||||
- Dynamical mapping is done by calling ``esp_mmap`` driver API :cpp:func:`esp_mmu_map`, this API will map the given physical memory block to a virtual memory block which is allocated by the ``esp_mmap`` driver.
|
||||
- Dynamical mapping is done by calling ``esp_mmap`` driver API :cpp:func:`esp_mmu_map`. This API maps the given physical memory block to a virtual memory block which is allocated by the ``esp_mmap`` driver.
|
||||
|
||||
|
||||
Relation Between Memory Blocks
|
||||
@ -86,22 +88,30 @@ When mapping a physical memory block A, block A can have one of the following re
|
||||
- Enclosed: block A is completely enclosed within block B, see figure below:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/enclosed.png
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
- Identical: block A is completely the same as block B, see figure below:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/identical.png
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
Note ``esp_mmap`` driver considers the identical scenario **the same as the enclosed scenario**.
|
||||
Note that ``esp_mmap`` driver considers the identical scenario **the same as the enclosed scenario**.
|
||||
|
||||
- Overlapped: block A is overlapped with block B, see figure below:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/overlapped.png
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
There is a special condition, when block A entirely encloses block B, see figure below:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/inversed_enclosed.png
|
||||
:scale: 70 %
|
||||
:align: center
|
||||
|
||||
``esp_mmap`` driver considers this scenario **the same as the overlapped scenario**.
|
||||
Note that ``esp_mmap`` driver considers this scenario **the same as the overlapped scenario**.
|
||||
|
||||
|
||||
Driver Behaviour
|
||||
@ -118,7 +128,7 @@ By default, physical memory blocks and virtual memory blocks are one-to-one mapp
|
||||
* If it is the identical scenario, this API will behaves exactly the same as the enclosed scenario.
|
||||
* If it is the overlapped scenario, this API will by default return an :c:macro:`ESP_ERR_INVALID_ARG`. This means, ``esp_mmap`` driver by default does not allow mapping a physical memory address to multiple virtual memory addresses.
|
||||
|
||||
Specially, you can use :c:macro:`ESP_MMU_MMAP_FLAG_PADDR_SHARED`. This flags stands for one-to-multiple mapping between a physical address and multiple virtual addresses:
|
||||
Specially, you can use :c:macro:`ESP_MMU_MMAP_FLAG_PADDR_SHARED`. This flag stands for one-to-multiple mapping between a physical address and multiple virtual addresses:
|
||||
|
||||
* If it is the overlapped scenario, this API will allocate a new virtual memory block as requested, then map to the given physical memory block.
|
||||
|
||||
@ -132,28 +142,28 @@ You can call :cpp:func:`esp_mmu_unmap` to unmap a previously mapped memory block
|
||||
Memory Address Conversion
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``esp_mmap`` driver provides two helper APIs to do the conversion between virtual memory address and physical memory address.
|
||||
The ``esp_mmap`` driver provides two helper APIs to do the conversion between virtual memory address and physical memory address:
|
||||
|
||||
* :cpp:func:`esp_mmu_vaddr_to_paddr`, convert virtual address to physical address.
|
||||
* :cpp:func:`esp_mmu_paddr_to_vaddr`, convert physical address to virtual address.
|
||||
* :cpp:func:`esp_mmu_vaddr_to_paddr` converts virtual address to physical address.
|
||||
* :cpp:func:`esp_mmu_paddr_to_vaddr` converts physical address to virtual address.
|
||||
|
||||
|
||||
Memory Synchronisation
|
||||
Memory Synchronization
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
MMU supported physical memories can be accessed by one or multiple methods.
|
||||
|
||||
SPI Flash can be accessed by SPI1 (ESP-IDF ``esp_flash`` driver APIs), or by pointers. ESP-IDF ``esp_flash`` driver APIs have already considered the memory synchronisation, so users do not need to worry about this.
|
||||
SPI flash can be accessed by SPI1 (ESP-IDF ``esp_flash`` driver APIs), or by pointers. ESP-IDF ``esp_flash`` driver APIs have already considered the memory synchronization, so users do not need to worry about this.
|
||||
|
||||
.. only:: SOC_SPIRAM_SUPPORTED
|
||||
|
||||
PSRAM can be accessed by pointers, hardware guarantees the data consistency when PSRAM is only accessed via pointers.
|
||||
PSRAM can be accessed by pointers, hardware guarantees the data consistency when PSRAM is only accessed via pointers.
|
||||
|
||||
.. only:: esp32s3
|
||||
|
||||
PSRAM can also be accessed by EDMA. Data desynchronisation may happen because hardware does not guarantee the data consistency under such condition. You should call :cpp:func:`esp_cache_msync` to synchronise the Cache and the PSRAM.
|
||||
PSRAM can also be accessed by EDMA. Data desynchronization may happen because hardware does not guarantee the data consistency under such condition. You should call :cpp:func:`esp_cache_msync` to synchronize the Cache and the PSRAM.
|
||||
|
||||
See :doc:`Memory Synchronization </api-reference/system/mm_sync>` for more details.
|
||||
See :doc:`/api-reference/system/mm_sync` for more details.
|
||||
|
||||
|
||||
Thread Safety
|
||||
|
@ -1 +1,183 @@
|
||||
.. include:: ../../../en/api-reference/system/mm.rst
|
||||
基于 MMU 的存储管理
|
||||
*******************
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
简介
|
||||
====
|
||||
|
||||
{IDF_TARGET_NAME} 的存储管理单元 (MMU) 相对简单。它可以在物理存储地址和虚拟存储地址之间进行存储地址转换,因此,CPU 可以通过虚拟存储地址来访问物理存储。虚拟存储地址有多种类型,分别具有不同的功能。
|
||||
|
||||
ESP-IDF 提供了一个存储器映射驱动程序,用于管理这些物理存储地址和虚拟存储地址之间的关系,实现一些功能。例如,可以通过指针从 SPI flash 中读取内容。
|
||||
|
||||
存储映射驱动程序实际上是一个基于属性的虚拟存储地址分配器,允许应用程序为不同的目的分配虚拟存储地址。下文将此驱动程序称为 ``esp_mmap`` 驱动程序。
|
||||
|
||||
ESP-IDF 还提供了一个存储器同步驱动程序来处理潜在的不同步的情况。
|
||||
|
||||
物理存储类型
|
||||
============
|
||||
|
||||
存储映射驱动程序目前支持映射到以下物理存储类型:
|
||||
|
||||
.. list::
|
||||
|
||||
- SPI flash
|
||||
:SOC_SPIRAM_SUPPORTED and not esp32: - PSRAM
|
||||
|
||||
|
||||
虚拟存储的功能
|
||||
==============
|
||||
|
||||
.. list::
|
||||
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_EXEC`:此功能表示虚拟存储地址具有执行权限。注意,此权限的范围仅限 MMU 硬件内部。
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_READ`:此功能表示虚拟存储地址具有读取权限。注意,此权限的范围仅限 MMU 硬件内部。
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_WRITE`:此功能表示虚拟存储地址具有写入权限。注意,此权限的范围仅限 MMU 硬件内部。
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_32BIT`:此功能表示允许访问 32 位或 32 位倍数的虚拟存储。
|
||||
- :cpp:enumerator:`MMU_MEM_CAP_8BIT`:此功能表示允许访问 8 位或 8 位倍数的虚拟存储。
|
||||
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
|
||||
由于硬件限制,不能分配具有 :cpp:enumerator:`MMU_MEM_CAP_EXEC` 和 :cpp:enumerator:`MMU_MEM_CAP_READ` 功能的 8 MB 外部存储地址(从 0x40400000 到 0x40C00000)。
|
||||
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
由于硬件限制,不能分配具有 :cpp:enumerator:`MMU_MEM_CAP_EXEC` 和 :cpp:enumerator:`MMU_MEM_CAP_READ` 功能的 4 MB 外部存储地址(从 0x40400000 到 0x40800000)。
|
||||
|
||||
|
||||
如需了解具有特定功能的最大连续可映射块大小,请调用 :cpp:func:`esp_mmu_map_get_max_consecutive_free_block_size`。
|
||||
|
||||
|
||||
存储管理驱动程序
|
||||
================
|
||||
|
||||
|
||||
驱动程序
|
||||
--------
|
||||
|
||||
|
||||
术语解释
|
||||
^^^^^^^^
|
||||
|
||||
虚拟存储池由一个或多个虚拟存储区域组成,如下图所示:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/mem_pool.png
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
|
||||
- 一个虚拟存储池是指可以映射到物理存储的整个虚拟地址范围。
|
||||
- 一个虚拟存储区域是指具有相同属性的虚拟地址范围。
|
||||
- 一个虚拟存储块是指一块动态映射的虚拟地址范围。
|
||||
- 一个间隙是指两个虚拟存储块之间的虚拟地址范围。
|
||||
- 一个物理存储块是指一块待映射或已映射到虚拟存储块的物理地址范围。
|
||||
- 动态映射是指调用 ``esp_mmap`` 驱动程序 API :cpp:func:`esp_mmu_map` 进行的映射,此 API 会将给定的物理存储块映射到 ``esp_mmap`` 驱动程序分配的虚拟存储块中。
|
||||
|
||||
|
||||
存储块的关系
|
||||
^^^^^^^^^^^^
|
||||
|
||||
在映射物理存储块 A 时,存储块 A 与此前已映射的另一个物理存储块 B 之间可能存在以下关系之一:
|
||||
|
||||
- 包含:块 A 被完全包含在块 B 内,如下图所示:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/enclosed.png
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
- 相同:块 A 与块 B 完全相同,如下图所示:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/identical.png
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
注意,``esp_mmap`` 驱动程序将相同 **视为包含**。
|
||||
|
||||
- 重叠:块 A 与块 B 重叠,如下图所示:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/overlapped.png
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
特殊情况下,当块 A 完全包围块 B 时,如下图所示:
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/inversed_enclosed.png
|
||||
:scale: 70 %
|
||||
:align: center
|
||||
|
||||
注意,``esp_mmap`` 驱动程序将这种情况 **视为重叠**。
|
||||
|
||||
|
||||
驱动程序行为
|
||||
------------
|
||||
|
||||
存储映射
|
||||
^^^^^^^^
|
||||
|
||||
可以调用 :cpp:func:`esp_mmu_map` 进行动态映射。该 API 会根据你所选择的虚拟存储的属性分配一定大小的虚拟存储块,然后按照要求将此虚拟存储块映射到物理存储块中。``esp_mmap`` 驱动程序支持映射到一种或多种物理存储,因此,应在映射时指定物理存储目标。
|
||||
|
||||
默认情况下,物理存储块和虚拟存储块是一对一映射。因此,当调用 :cpp:func:`esp_mmu_map` 时,如果存储关系不同,API 的行为也有所不同:
|
||||
|
||||
* 如果是“包含”的情形,此 API 将返回 :c:macro:`ESP_ERR_INVALID_STATE`。此时,由于之前已映射的虚拟存储包含待映射的虚拟存储,因此返回的 ``out_ptr`` 会指向之前映射的虚拟存储的起始地址。
|
||||
* 如果是“相同”的情形,此 API 的行为与“包含”的情况完全相同。
|
||||
* 如果是“重叠”的情形,此 API 默认返回 :c:macro:`ESP_ERR_INVALID_ARG`。这表明,``esp_mmap`` 驱动程序在默认情况下,不允许将一个物理存储地址映射到多个虚拟存储地址。
|
||||
|
||||
但是,可以使用 :c:macro:`ESP_MMU_MMAP_FLAG_PADDR_SHARED` flag,代表在物理地址和虚拟地址之间的一对多映射:
|
||||
|
||||
* 如果是“重叠”的情形,此 API 将按照要求分配一个新的虚拟存储块,并将其映射到给定的物理存储块中。
|
||||
|
||||
|
||||
取消存储映射
|
||||
^^^^^^^^^^^^
|
||||
|
||||
可以调用 :cpp:func:`esp_mmu_unmap` 来取消先前存储块的映射。如果尝试取消映射的虚拟存储块实际尚未映射到任何物理存储块,此 API 将返回 :c:macro:`ESP_ERR_NOT_FOUND`。
|
||||
|
||||
|
||||
存储地址转换
|
||||
^^^^^^^^^^^^
|
||||
|
||||
``esp_mmap`` 驱动程序提供了两个辅助 API,用于虚拟存储地址和物理存储地址之间的转换:
|
||||
|
||||
* :cpp:func:`esp_mmu_vaddr_to_paddr` 可将虚拟存储地址转换为物理存储地址。
|
||||
* :cpp:func:`esp_mmu_paddr_to_vaddr` 可将物理存储地址转换为虚拟存储地址。
|
||||
|
||||
|
||||
存储同步
|
||||
^^^^^^^^
|
||||
|
||||
可以通过一种或多种方法来访问支持 MMU 的物理存储。
|
||||
|
||||
SPI flash 可以通过 SPI1(ESP-IDF ``spi_flash`` 驱动 API)或指针进行访问。ESP-IDF ``spi_flash`` 驱动 API 中已经考虑了存储同步,因此在使用时无需额外考虑存储同步。
|
||||
|
||||
.. only:: SOC_SPIRAM_SUPPORTED
|
||||
|
||||
PSRAM 可以通过指针进行访问。当只通过指针访问 PSRAM 时,硬件可以保证数据的一致性。
|
||||
|
||||
.. only:: esp32s3
|
||||
|
||||
PSRAM 也可以通过 EDMA 进行访问,但有可能发生数据不同步的问题。因为在这种情况下,硬件不能保证数据的一致性。应调用 :cpp:func:`esp_cache_msync` 来同步 cache 和 PSRAM。
|
||||
|
||||
如需了解更多内容,请参考 :doc:`/api-reference/system/mm_sync`。
|
||||
|
||||
|
||||
线程安全
|
||||
========
|
||||
|
||||
``esp_mmu_map.h`` 中的 API 不能确保线程的安全性。
|
||||
|
||||
``esp_cache.h`` 中的 API 能够确保线程的安全性。
|
||||
|
||||
|
||||
API 参考
|
||||
========
|
||||
|
||||
API 参考 - ESP MMAP 驱动
|
||||
-------------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_mmu_map.inc
|
||||
|
Loading…
x
Reference in New Issue
Block a user