mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
docs: Provide CN Translation for mm_sync.rst in api-reference
This commit is contained in:
parent
95ab3ccf96
commit
7ddc3755ac
@ -1,6 +1,8 @@
|
||||
Memory Synchronization
|
||||
**********************
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
@ -29,7 +31,7 @@ This leads to potential cache data coherence issue:
|
||||
- When a DMA transaction changes the content of a piece of memory, and the content has been cached already. Under this condition:
|
||||
|
||||
- CPU may read stale data.
|
||||
- the stale data in the cache may be written back to the memory. The new data updated by the previous DMA transaction will be overwritten.
|
||||
- The stale data in the cache may be written back to the memory. The new data updated by the previous DMA transaction will be overwritten.
|
||||
|
||||
- CPU changes the content of an address. The content is in the cache, but not in the memory yet (cache will write back the content to the memory according to its own strategy). Under this condition:
|
||||
|
||||
@ -40,11 +42,11 @@ There are three common methods to address such cache data coherence issue:
|
||||
.. list::
|
||||
|
||||
1. Hardware based cache Coherent Interconnect, {IDF_TARGET_NAME} does not have such ability.
|
||||
2. Use the DMA buffer from non-cacheable memory. Memory that CPU access it without going through cache is called non-cacheable memory.
|
||||
2. Use the DMA buffer from non-cacheable memory. Non-cacheable memory refers to the type of memory that is accessed by CPU without going through cache.
|
||||
3. Explicitly call a memory synchronization API to writeback the content in the cache back to the memory, or invalidate the content in the cache.
|
||||
|
||||
|
||||
Memory Synchronisation Driver
|
||||
Memory Synchronization Driver
|
||||
=============================
|
||||
|
||||
The suggested way to deal with such cache data coherence issue is by using the memory synchronization API :cpp:func:`esp_cache_msync` provided by ESP-IDF `esp_mm` component.
|
||||
@ -71,7 +73,7 @@ Calling :cpp:func:`esp_cache_msync` will do a synchronization between cache and
|
||||
|
||||
.. list::
|
||||
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_C2M`. With this flag, content in the specified address region is written back to the memory. This direction is usually used **after** the content of an address is updated by the CPU, e.g. a memset to the address. Operation in this direction should happen **before** a DMA operation to the same address.
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_C2M`. With this flag, content in the specified address region is written back to the memory. This direction is usually used **after** the content of an address is updated by the CPU, e.g., a memset to the address. Operation in this direction should happen **before** a DMA operation to the same address.
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_M2C`. With this flag, content in the specified address region is invalidated from the cache. This direction is usually used **after** the content of an address is updated by the DMA. Operation in this direction should happen **before** a CPU read operation to the same address.
|
||||
|
||||
The above two flags help select the synchronization direction. Specially, if neither of these two flags are used, :cpp:func:`esp_cache_msync` will by default select the :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_C2M` direction. Users are not allowed to set both of the two flags at the same time.
|
||||
@ -81,13 +83,13 @@ The above two flags help select the synchronization direction. Specially, if nei
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_DATA`.
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_INST`.
|
||||
|
||||
The above two flags help select the type of the synchronization address. Specially, if neither of these two flags are used, :cpp:func:`esp_cache_msync` will by default select the :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_DATA` direction. Users are not allowed to set both of the two flags at the same time.
|
||||
The above two flags help select the type of the synchronization address. Specially, if neither of these two flags are used, :cpp:func:`esp_cache_msync` will by default select the :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_DATA` type. Users are not allowed to set both of the two flags at the same time.
|
||||
|
||||
|
||||
.. list::
|
||||
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_INVALIDATE`. This flag is used to trigger a cache invalidation to the specified address region, after the region is written back to the memory. This flag is mainly used for :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_C2M` direction. For :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_M2C` direction, behaviour is the same as if the :c:macro:`ESP_CACHE_MSYNC_FLAG_INVALIDATE` flag is not set.
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_UNALIGNED`. This flag force the :cpp:func:`esp_cache_msync` API to do synchronization without checking the address and size alignment. For more details, see chapter `Address Alignment Requirement` following.
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_UNALIGNED`. This flag force the :cpp:func:`esp_cache_msync` API to do synchronization without checking the address and size alignment. For more details, see section `Address Alignment Requirement` following.
|
||||
|
||||
|
||||
Address Alignment Requirement
|
||||
@ -106,8 +108,8 @@ Memory Allocation Helper
|
||||
|
||||
cache memory synchronization is usually considered when DMA is involved. ESP-IDF provides an API to do memory allocation that can meet the alignment requirement from both the cache and the DMA.
|
||||
|
||||
- :cpp:func:`esp_dma_capable_malloc`, this API allocates a chunk of memory that meets the alignment requirement from both the cache and the DMA.
|
||||
- :cpp:func:`esp_dma_capable_calloc`, this API allocates a chunk of memory that meets the alignment requirement from both the cache and the DMA. The initialized value in the memory is set to zero.
|
||||
- :cpp:func:`esp_dma_capable_malloc`. This API allocates a chunk of memory that meets the alignment requirement from both the cache and the DMA.
|
||||
- :cpp:func:`esp_dma_capable_calloc`. This API allocates a chunk of memory that meets the alignment requirement from both the cache and the DMA. The initialized value in the memory is set to zero.
|
||||
|
||||
You can also use :c:macro:`ESP_DMA_MALLOC_FLAG_PSRAM` to allocate from the PSRAM.
|
||||
|
||||
@ -115,7 +117,7 @@ You can also use :c:macro:`ESP_DMA_MALLOC_FLAG_PSRAM` to allocate from the PSRAM
|
||||
Warning for Address Alignment Requirement
|
||||
-----------------------------------------
|
||||
|
||||
You can set the :c:macro:`ESP_CACHE_MSYNC_FLAG_UNALIGNED` flag to bypass such check. Note you should be very careful about using this flag. cache memory synchronization to an unaligned address region may silently corrupt the memory.
|
||||
You can set the :c:macro:`ESP_CACHE_MSYNC_FLAG_UNALIGNED` flag to bypass such check. Note you should be very careful about using this flag. Cache memory synchronization to an unaligned address region may silently corrupt the memory.
|
||||
|
||||
For example, assume:
|
||||
|
||||
|
@ -1 +1,148 @@
|
||||
.. include:: ../../../en/api-reference/system/mm_sync.rst
|
||||
内存同步
|
||||
********
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
|
||||
简介
|
||||
====
|
||||
|
||||
.. only:: SOC_PSRAM_DMA_CAPABLE
|
||||
|
||||
{IDF_TARGET_NAME} 可以通过以下方式访问其连接的 PSRAM:
|
||||
|
||||
- CPU
|
||||
- DMA
|
||||
|
||||
.. only:: SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
|
||||
{IDF_TARGET_NAME} 可以通过以下方式访问其内存:
|
||||
|
||||
- CPU
|
||||
- DMA
|
||||
|
||||
默认情况下,CPU 通过 cache 访问上述内存,而 DMA 则可以直接访问内存。
|
||||
|
||||
这可能导致 cache 数据不一致的问题:
|
||||
|
||||
- 当 DMA 事务更改内存块的内容,并且该内容已经加载到 cache 中时:
|
||||
|
||||
- CPU 可能会读取陈旧数据。
|
||||
- cache 中的陈旧数据可能会被写回到内存中,而 DMA 事务更新的新数据将被覆盖。
|
||||
|
||||
- 当 CPU 更改了地址的内容,内容已经加载至 cache 中,但还未存在于内存中(cache 会根据自己的策略将内容写回内存)时:
|
||||
|
||||
- 下一个 DMA 事务从内存中读取此内容,将会获取陈旧数据。
|
||||
|
||||
解决此类 cache 数据不一致问题的常见方法有三种:
|
||||
|
||||
.. list::
|
||||
|
||||
1. 基于硬件的 cache 一致性互连,{IDF_TARGET_NAME} 没有此功能。
|
||||
2. 使用来自 non-cacheable 内存的 DMA 缓冲区(CPU 绕过 cache 访问的内存被称为 non-cacheable 内存)。
|
||||
3. 显式调用内存同步 API 将 cache 中的内容写回到内存,或使 cache 中的内容无效化。
|
||||
|
||||
|
||||
内存同步驱动程序
|
||||
================
|
||||
|
||||
建议使用 ESP-IDF 的 `esp_mm` 组件所提供的内存同步 API :cpp:func:`esp_cache_msync` 来处理此类 cache 数据不一致的问题。
|
||||
|
||||
|
||||
驱动程序的概念
|
||||
--------------
|
||||
|
||||
cache 与内存同步的方向:
|
||||
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_C2M`,用于从 cache 到内存的同步。
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_M2C`,用于从内存到 cache 的同步。
|
||||
|
||||
cache 与内存同步的类型:
|
||||
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_DATA`,用于同步到数据地址区域。
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_INST`,用于同步到指令地址区域。
|
||||
|
||||
|
||||
驱动程序的行为
|
||||
--------------
|
||||
|
||||
调用 :cpp:func:`esp_cache_msync`,可以同步 cache 和内存。第一个参数 `addr` 和第二个参数 `size` 共同描述了要同步的内存区域。关于第三个参数 `flags`:
|
||||
|
||||
.. list::
|
||||
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_C2M`。使用此标志,指定地址区域中的内容将被写回到内存中。这一方向通常在 CPU 更新地址内容 **之后** 使用(例如对地址执行 memset 后),且需要在 DMA 对同一地址进行操作 **之前** 使用。
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_M2C`。使用此标志,指定地址区域中的内容在 cache 中将无效化。这一方向通常在 DMA 更新地址内容 **之后** 使用,且需要在 CPU 将操作读取到同一地址 **之前** 使用。
|
||||
|
||||
上述两个标志用于选择同步的方向,不能同时使用。如果两个标志都未使用, :cpp:func:`esp_cache_msync` 将默认选择 :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_C2M`。
|
||||
|
||||
.. list::
|
||||
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_DATA`。
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_INST`。
|
||||
|
||||
上述两个标志能帮助选择同步地址的类型,不能同时使用,且如果没有用其中任何一个,则 :cpp:func:`esp_cache_msync` 将默认选择 :c:macro:`ESP_CACHE_MSYNC_FLAG_TYPE_DATA`。
|
||||
|
||||
|
||||
.. list::
|
||||
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_INVALIDATE`。将特定地址区域写回内存后,可使用此标志触发区域内 cache 失效。此标志主要用于 :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_C2M` 方向。设置 :c:macro:`ESP_CACHE_MSYNC_FLAG_INVALIDATE` 标志对 :c:macro:`ESP_CACHE_MSYNC_FLAG_DIR_M2C` 方向不会产生任何效果。
|
||||
- :c:macro:`ESP_CACHE_MSYNC_FLAG_UNALIGNED`。此标志会强制 :cpp:func:`esp_cache_msync` API 在不检查地址对齐和大小对齐的情况下执行同步,详情请参阅下文 `地址对齐的要求` 章节。
|
||||
|
||||
|
||||
地址对齐的要求
|
||||
==============
|
||||
|
||||
使用 :cpp:func:`esp_cache_msync` 时,对地址和大小(以字节为单位)存在来自 cache 的对齐要求。
|
||||
|
||||
- 起始地址和大小都符合 cache 与内存同步对齐要求的地址区域被称为 **对齐地址区域**。
|
||||
- 起始地址或大小不符合 cache 与内存同步对齐要求的地址区域被称为 **非对齐地址区域**。
|
||||
|
||||
默认情况下,如果指定了非对齐地址区域,则 :cpp:func:`esp_cache_msync` 将报错 :c:macro:`ESP_ERR_INVALID_ARG`,并告知所需的对齐方式。
|
||||
|
||||
|
||||
内存分配助手
|
||||
------------
|
||||
|
||||
在涉及 DMA 时通常会考虑同步 cache 和内存。ESP-IDF 提供了能进行内存分配的 API,可同时满足 cache 和 DMA 的对齐要求。
|
||||
|
||||
- :cpp:func:`esp_dma_capable_malloc`。此 API 可分配一块满足 cache 和 DMA 对齐要求的内存块。
|
||||
- :cpp:func:`esp_dma_capable_calloc`。此 API 可分配一块满足 cache 和 DMA 对齐要求的内存块,且内存中的初始化值已设置为零。
|
||||
|
||||
也可以使用 :c:macro:`ESP_DMA_MALLOC_FLAG_PSRAM`, 从 PSRAM 中分配内存。
|
||||
|
||||
|
||||
有关地址对齐要求的警告
|
||||
----------------------
|
||||
|
||||
可以通过设置 :c:macro:`ESP_CACHE_MSYNC_FLAG_UNALIGNED` 标志跳过此类检查。但请注意,使用此标志需谨慎,因为在非对齐地址区域内同步 cache 和内存可能会在无形中破坏内存。
|
||||
|
||||
举个例子,假设:
|
||||
|
||||
- 对齐要求为 0x40 字节。
|
||||
- 调用 :cpp:func:`esp_cache_msync`,并使用 `ESP_CACHE_MSYNC_FLAG_DIR_M2C | ESP_CACHE_MSYNC_FLAG_UNALIGNED` 标志,指定的地址区域为 0x4000_0020 ~ 0x4000_0060(详见下图中的 **data C**)。
|
||||
|
||||
上述设置将触发地址区域 0x4000_0000 ~ 0x4000_0080 cache 失效,详见下图中的 **sync item0** 和 **sync item1**。
|
||||
|
||||
如果 0x4000_0000 ~ 0x4000_0020 中的内容(下图中的 **data A**)或 0x4000_0060 ~ 0x4000_0080 中的内容(下图中的 **data B**)尚未写回到内存,则 **data A** 和 **data B** 将被丢弃。
|
||||
|
||||
.. image:: /../_static/diagrams/mmu/cache_align_issue.png
|
||||
:scale: 80 %
|
||||
:align: center
|
||||
|
||||
|
||||
API 参考
|
||||
========
|
||||
|
||||
API 参考 - ESP Msync 驱动程序
|
||||
-----------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_cache.inc
|
||||
|
||||
|
||||
API 参考 - ESP DMA 实用程序
|
||||
---------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_dma_utils.inc
|
||||
|
Loading…
x
Reference in New Issue
Block a user