update CN translation for ulp.rst index.rst bootloader.rst and external-ram.rst under api-guides section

This commit is contained in:
Dai Zi Yan 2021-01-08 17:49:09 +08:00 committed by Krzysztof Budzynski
parent fee77509a9
commit 694dd2767a
4 changed files with 122 additions and 92 deletions

View File

@ -10,20 +10,25 @@
引导加载程序位于 Flash 的 `0x1000` 偏移地址处。 引导加载程序位于 Flash 的 `0x1000` 偏移地址处。
引导加载程序兼容性
-------------------
建议使用最新发布的 :doc:`ESP-IDF 版本 </versions>`。OTA空中升级更新可以在现场烧录新的应用程序但不能烧录一个新的引导加载程序。因此引导加载程序支持引导从 ESP-IDF 新版本中构建的应用程序。
但不支持引导从 ESP-IDF 旧版本中构建的程序。如果现有产品可能需要将应用程序降级到旧版本,那么在手动更新 ESP-IDF 时,请继续使用旧版本 ESP-IDF 引导加载程序的二进制文件。
恢复出厂设置 恢复出厂设置
------------ ------------
用户可以编写一个基本的工作固件然后将其加载到工厂分区factory中。 用户可以编写一个基本的工作固件然后将其加载到工厂分区factory中。
接下来,通过 OTA空中升级更新固件更新后的固件会被保存到某个 OTA app 分区中OTA 数据分区也会做相应更新以指示从该分区引导应用程序。 接下来,通过 OTA空中升级更新固件更新后的固件会被保存到某个 OTA app 分区中OTA 数据分区也会做相应更新以指示从该分区引导应用程序。
如果你希望回滚到出厂固件并清除设置,则需要设置 :ref:`CONFIG_BOOTLOADER_FACTORY_RESET` 如果你希望回滚到出厂固件并清除设置,则需要设置 :ref:`CONFIG_BOOTLOADER_FACTORY_RESET`。出厂重置机制允许将设备重置为出厂模式:
出厂重置机制允许将设备重置为出厂模式:
- 清除一个或多个数据分区。 - 清除一个或多个数据分区。
- 从工厂分区启动。 - 从工厂分区启动。
:ref:`CONFIG_BOOTLOADER_DATA_FACTORY_RESET` - 允许用户选择在恢复出厂设置时需要除的数据分区。可以通过逗号来分隔多个分区的名字,并适当增加空格以便阅读(例如 "nvs, phy_init, nvs_custom, ...")。请确保此处指定的名称和分区表中的名称相同,且不含有 “app” 类型的分区。 :ref:`CONFIG_BOOTLOADER_DATA_FACTORY_RESET` - 允许用户选择在恢复出厂设置时需要除的数据分区。可以通过逗号来分隔多个分区的名字,并适当增加空格以便阅读(例如 "nvs, phy_init, nvs_custom, ...")。请确保此处指定的名称和分区表中的名称相同,且不含有 “app” 类型的分区。
:ref:`CONFIG_BOOTLOADER_OTA_DATA_ERASE` - 恢复出厂模式后设备会从工厂分区启动OTA 数据分区会被清除。 :ref:`CONFIG_BOOTLOADER_OTA_DATA_ERASE` - 恢复出厂模式后设备会从工厂分区启动OTA 数据分区会被清除。
@ -45,17 +50,27 @@
.. _bootloader_boot_from_test_firmware: .. _bootloader_boot_from_test_firmware:
从测试固件启动 从测试应用程序分区启动
-------------- ------------------------
用户可以编写在生产环境中测试用的特殊固件,然后在需要的时候运行。此时需要在分区表中专门申请一块分区用于保存该测试固件(详情请参阅 :doc:`分区表 <partition-tables>`)。如果想要触发测试固件,还需要设置 :ref:`CONFIG_BOOTLOADER_APP_TEST` 用户可以编写特殊固件用于生产环境中测试,然后在需要的时候运行。此时需要在分区表中专门申请一块分区用于保存该测试固件(详情请参阅 :doc:`分区表 <partition-tables>`)。如果想要触发测试固件,还需要设置 :ref:`CONFIG_BOOTLOADER_APP_TEST`
:ref:`CONFIG_BOOTLOADER_NUM_PIN_APP_TEST` - 设置引导测试分区的 GPIO 管脚编号,该 GPIO 会被配置为输入模式,并且会使能内部上拉电阻。若想触发测试固件,该 GPIO 必须在芯片复位时拉低。设备重启时如果该 GPIO 没有被激活(即处于高电平状态),那么会加载常规配置的应用程序(可能位于工厂分区或者 OTA 分区)。 :ref:`CONFIG_BOOTLOADER_NUM_PIN_APP_TEST` - 设置引导测试分区的 GPIO 管脚编号,该 GPIO 会被配置为输入模式,并且会使能内部上拉电阻。若想触发测试固件,该 GPIO 必须在芯片复位时拉低。设备重启时如果该 GPIO 没有被激活(即处于高电平状态),那么会加载常规配置的应用程序(可能位于工厂分区或者 OTA 分区)。
:ref:`CONFIG_BOOTLOADER_HOLD_TIME_GPIO` - 设置进入重置或测试模式所需要的保持时间(默认为 5 秒。设备复位后GPIO 必须在这段时间内持续保持低电平,然后才会执行出厂重置或引导测试分区。 :ref:`CONFIG_BOOTLOADER_HOLD_TIME_GPIO` - 设置进入重置或测试模式所需要的保持时间(默认为 5 秒。设备复位后GPIO 必须在这段时间内持续保持低电平,然后才会执行出厂重置或引导测试分区。
从深度睡眠中快速启动
----------------------
引导加载程序有 :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` 选项,可以减少唤醒时间(有利于降低消耗)。当 :ref:`CONFIG_SECURE_BOOT` 选项禁用时,该选项可用。由于无需固件校验,唤醒时间减少。在第一次启动时,引导加载程序将启动的应用程序的地址存储在 RTC FAST 存储器中。而在唤醒过程中,这个地址用于启动而无需任何检查,从而实现了快速加载。
自定义引导程序 自定义引导程序
-------------- --------------
用户可以重写当前的引导加载程序,具体做法是,复制 `/esp-idf/components/bootloader` 文件夹到项目目录中,然后编辑 `/your_project/components/bootloader/subproject/ain/bootloader_main.c` 文件。 用户可以重写当前的引导加载程序,具体做法是,复制 `/esp-idf/components/bootloader` 文件夹到项目组件目录中,然后编辑 ``/your_project/components/bootloader/subproject/main/bootloader_start.c`` 文件。
在引导加载程序的代码中,用户不可以使用驱动和其他组件提供的函数,如果确实需要,请将该功能的实现部分放在 bootloader 目录中(注意,这会增加引导程序的大小)。监视生成的引导程序的大小是有必要的,因为它可能会与内存中的分区表发生重叠而损坏固件。目前,引导程序被限制在了分区表之前的区域(分区表位于 `0x8000` 地址处)。 在引导加载程序的代码中,用户不能使用其他组件提供的驱动和函数,如果确实需要,请将该功能的实现部分放在项目的 bootloader 目录中(注意,这会增加引导程序的大小)。
如果引导程序过大,则可能与内存中的分区表重叠,分区表默认烧录在
偏移量 0x8000 处。增加 :ref:`分区表偏移量值 <CONFIG_PARTITION_TABLE_OFFSET>` ,将分区表放在 flash 中靠后的区域,这样可以增加引导程序的可用空间。
.. note:: 初次将引导程序复制到现有项目中时,由于路径发生了意外变化,项目可能无法构建。对于这种情况,请运行 ``idf.py fullclean`` (或删除项目构建目录),然后重新构建。

View File

@ -9,35 +9,27 @@
简介 简介
============ ============
{IDF_TARGET_NAME} 提供了 520 KB 的片上 SRAM可以满足大部分需求。但有些场景可能需要更多 RAM因此 {IDF_TARGET_NAME} 另外提供了高达 4 MB 的片外 SPI RAM 存储器以供用户使用。片外 RAM 被添加到内存映射中,在某些范围内与片上 RAM 使用方式相同。 {IDF_TARGET_NAME} 提供了好几百 KB 的片上 RAM可以满足大部分需求。但有些场景可能需要更多 RAM因此 {IDF_TARGET_NAME} 另外提供了高达 4 MB 的片外 SPI RAM 存储器以供用户使用。片外 RAM 被添加到内存映射中,在某些范围内与片上 RAM 使用方式相同。
硬件 硬件
======== ========
{IDF_TARGET_NAME} 支持与 SPI Flash 芯片并联的 SPI PSRAM。{IDF_TARGET_NAME} 支持多种类型的 RAM 芯片,但 {IDF_TARGET_NAME} SDK 当前仅支持 ESP-PSRAM32 芯片 {IDF_TARGET_NAME} 支持与 SPI Flash 芯片并联的 SPI PSRAM。虽然 {IDF_TARGET_NAME} 支持多种类型的 RAM 芯片,但 ESP-IDF 当前仅支持乐鑫品牌的 PSRAM 芯片,如 ESP-PSRAM32、ESP-PSRAM64 等
ESP-PSRAM32 芯片的工作电压为 1.8 V只能与 1.8 V flash 并联使用。请确保在启动时将 MTDI 管脚设置为高电平,或者将 {IDF_TARGET_NAME} 中的熔丝设置为始终使用 1.8 V 的 VDD_SIO 电平,否则有可能会损坏 PSRAM 和/或 flash 芯片。 .. note:: PSRAM 芯片的工作电压分为 1.8 V 和 3.3 V。其工作电压必须与 flash 的工作电压匹配。请查询您 PSRAM 芯片以及 {IDF_TARGET_NAME} 的技术规格书获取准确的工作电压。对于 1.8 V 的 PSRAM 芯片,请确保在启动时将 MTDI 管脚设置为高电平,或者将 {IDF_TARGET_NAME} 中的 eFuses 设置为始终使用 1.8 V 的 VDD_SIO 电平,否则有可能会损坏 PSRAM 和/或 flash 芯片。
要将 ESP-PSRAM 芯片连接到 ESP32D0W*,请连接以下信号: .. note:: 乐鑫同时提供模组和系统级封装芯片,集成了兼容的 PSRAM 和 flash可直接用于终端产品 PCB 中。如需了解更多信息,请前往乐鑫官网。
* PSRAM /CE (pin 1) > ESP32 GPIO 16
* PSRAM SO (pin 2) > flash DO
* PSRAM SIO[2] (pin 3) > flash WP
* PSRAM SI (pin 5) > flash DI
* PSRAM SCLK (pin 6) > ESP32 GPIO 17
* PSRAM SIO[3] (pin 7) > flash HOLD
* PSRAM Vcc (pin 8) > ESP32 VCC_SDIO
ESP32D2W* 芯片的连接方式有待确定。 有关将 SoC 或模组管脚连接到片外 PSRAM 芯片的具体细节,请查阅 SoC 或模组技术规格书。
.. note::
乐鑫同时提供 ESP32-WROVER 模组,内部搭载 ESP32 芯片,集成 1.8 V flash 和 ESP-PSRAM32可直接用于终端产品 PCB 中。
.. _external_ram_config: .. _external_ram_config:
配置片外 RAM 配置片外 RAM
======================== ========================
ESP-IDF 完全支持将外部存储器集成到您的应用程序中。您可以将 ESP-IDF 配置成启动并完成初始化后以多种方式处理片外 RAM ESP-IDF 完全支持将外部存储器集成到您的应用程序中。在启动并完成片外 RAM 初始化后,可以将 ESP-IDF 配置为以多种方式处理片外 RAM
* :ref:`external_ram_config_memory_map` * :ref:`external_ram_config_memory_map`
* :ref:`external_ram_config_capability_allocator` * :ref:`external_ram_config_capability_allocator`
@ -46,38 +38,41 @@ ESP-IDF 完全支持将外部存储器集成到您的应用程序中。您可以
.. _external_ram_config_memory_map: .. _external_ram_config_memory_map:
集成片外 RAM 到 {IDF_TARGET_NAME} 内存映射
---------------------------------------
:ref:`CONFIG_SPIRAM_USE` 中选择 "Integrate RAM into {IDF_TARGET_NAME} memory map集成片外 RAM 到 {IDF_TARGET_NAME} 内存映射)" 选项。 集成片外 RAM 到 {IDF_TARGET_NAME} 内存映射
-------------------------------------------
:ref:`CONFIG_SPIRAM_USE` 中选择 "Integrate RAM into memory map集成片外 RAM 到 {IDF_TARGET_NAME} 内存映射)" 选项。
这是集成片外 RAM 最基础的设置选项,大多数用户需要用到其他更高级的选项。 这是集成片外 RAM 最基础的设置选项,大多数用户需要用到其他更高级的选项。
ESP-IDF 启动过程中,片外 RAM 被映射到以 0x3F800000 起始的数据地址空间(字节可寻址),空间大小正好为 RAM 的大小 (4 MB)。 ESP-IDF 启动过程中,片外 RAM 被映射到以 0x3F800000 起始的数据地址空间(字节可寻址),空间大小正好为 SPI RAM 的大小 (4 MB)。
应用程序可以通过创建指向该区域的指针手动将数据放入片外存储器,同时应用程序全权负责管理片外 RAM包括协调 Buffer 的使用、防止发生损坏等。 应用程序可以通过创建指向该区域的指针手动将数据放入片外存储器,同时应用程序全权负责管理片外 SPI RAM包括协调 Buffer 的使用、防止发生损坏等。
.. _external_ram_config_capability_allocator: .. _external_ram_config_capability_allocator:
添加片外 RAM 到内存分配程序
-------------------------------------------- 添加片外 RAM 到堆内存分配器
----------------------------
:ref:`CONFIG_SPIRAM_USE` 中选择 "Make RAM allocatable using heap_caps_malloc(..., MALLOC_CAP_SPIRAM)" 选项。 :ref:`CONFIG_SPIRAM_USE` 中选择 "Make RAM allocatable using heap_caps_malloc(..., MALLOC_CAP_SPIRAM)" 选项。
启用上述选项后,片外 RAM 被映射到地址 0x3F800000并将这个区域添加到 :doc:`内存分配程序 </api-reference/system/mem_alloc>` 里携带 ``MALLOC_CAP_SPIRAM`` 的标志 启用上述选项后,片外 RAM 被映射到地址 0x3F800000并将这个区域添加到 :doc:`堆内存分配器 </api-reference/system/mem_alloc>` 里携带 ``MALLOC_CAP_SPIRAM`` 的标志
程序如果想从片外存储器分配存储空间,则需要调用 ``heap_caps_malloc(size, MALLOC_CAP_SPIRAM)``,之后可以调用 ``free()`` 函数释放这部分存储空间。 程序如果想从片外存储器分配存储空间,则需要调用 ``heap_caps_malloc(size, MALLOC_CAP_SPIRAM)``,之后可以调用 ``free()`` 函数释放这部分存储空间。
.. _external_ram_config_malloc: .. _external_ram_config_malloc:
调用 malloc() 分配片外 RAM 调用 malloc() 分配片外 RAM
--------------------------------- ---------------------------------
:ref:`CONFIG_SPIRAM_USE` 中选择 "Make RAM allocatable using malloc() as well" 选项,该选项为默认选项。 :ref:`CONFIG_SPIRAM_USE` 中选择 "Make RAM allocatable using malloc() as well" 选项,该选项为默认选项。
启用此选项后,片外存储器将被添加到内存分配程序(与上一选项相同),同时也将被添加到由标准 ``malloc()`` 返回的 RAM 中。 启用此选项后,片外存储器将被添加到内存分配程序(与上一选项相同),同时也将被添加到由标准 ``malloc()`` 函数返回的 RAM 中。
这允许应用程序使用片外 RAM 而无需重写代码以使用 ``heap_caps_malloc(..., MALLOC_CAP_SPIRAM)`` 这允许应用程序使用片外 RAM,无需重写代码就能使用 ``heap_caps_malloc(..., MALLOC_CAP_SPIRAM)``
如果某次内存分配偏向于片外存储器,您也可以使用 :ref:`CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL` 设置分配空间的大小阈值,控制分配结果: 如果某次内存分配偏向于片外存储器,您也可以使用 :ref:`CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL` 设置分配空间的大小阈值,控制分配结果:
@ -90,18 +85,21 @@ ESP-IDF 启动过程中,片外 RAM 被映射到以 0x3F800000 起始的数据
.. _external_ram_config_bss: .. _external_ram_config_bss:
允许 .bss 段放入片外存储器
--------------------------------------------
设置 :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` 启用该选项,此选项配置与上面三个选项互不影响。 允许 .bss 段放入片外存储器
-----------------------------
通过检查 :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` 启用该选项,此选项配置与上面三个选项互不影响。
启用该选项后,从 0x3F800000 起始的地址空间将用于存储来自 lwip、net80211、libpp 和 bluedroid ESP-IDF 库中零初始化的数据BSS 段)。 启用该选项后,从 0x3F800000 起始的地址空间将用于存储来自 lwip、net80211、libpp 和 bluedroid ESP-IDF 库中零初始化的数据BSS 段)。
``EXT_RAM_ATTR`` 宏应用于任何静态声明(未初始化为非零值)之后,可以将附加数据从内部 BSS 段移到片外 RAM。 ``EXT_RAM_ATTR`` 宏应用于任何静态声明(未初始化为非零值)之后,可以将附加数据从内部 BSS 段移到片外 RAM。
也可以使用链接器片段方案 ``extram_bss`` 将组件或库的 BSS 段放到片外 RAM 中。
启用此选项可以减少 BSS 段占用的内部静态存储。 启用此选项可以减少 BSS 段占用的内部静态存储。
剩余的片外 RAM 也可以通过上述方法添加到内存分配程序中。 剩余的片外 RAM 也可以通过上述方法添加到堆分配器中。
片外 RAM 使用限制 片外 RAM 使用限制
=================== ===================
@ -110,9 +108,9 @@ ESP-IDF 启动过程中,片外 RAM 被映射到以 0x3F800000 起始的数据
* Flash cache 禁用时(比如,正在写入 flash片外 RAM 将无法访问;同样,对片外 RAM 的读写操作也将导致 cache 访问异常。出于这个原因ESP-IDF 不会在片外 RAM 中分配任务堆栈(详见下文)。 * Flash cache 禁用时(比如,正在写入 flash片外 RAM 将无法访问;同样,对片外 RAM 的读写操作也将导致 cache 访问异常。出于这个原因ESP-IDF 不会在片外 RAM 中分配任务堆栈(详见下文)。
* 片外 RAM 不能用于储存 DMA 描述符,也不能用作 DMA 读写操作的缓冲区 (Buffer)。与 DMA 搭配使用的 Buffer 必须先使用 ``heap_caps_malloc(size, MALLOC_CAP_DMA)`` 进行分配,之后可以调用标准 ``free()`` 回调释放 Buffer。 * 片外 RAM 不能用于储存 DMA 事物描述符,也不能用作 DMA 读写操作的缓冲区 (Buffer)。与 DMA 搭配使用的 Buffer 必须先使用 ``heap_caps_malloc(size, MALLOC_CAP_DMA)`` 进行分配,之后可以调用标准 ``free()`` 回调释放 Buffer。
* 片外 RAM 与片外 flash 使用相同的 cache 区域,频繁在片外 RAM 访问的变量可以像在片上 RAM 中一样快速读取和修改。但访问大块数据时(大于 32 KBcache 空间可能会不足,访问速度将回落到片外 RAM 访问速度。此外,访问大块数据可以挤出 flash cache可能会降低代码执行速度。 * 片外 RAM 与片外 flash 使用相同的 cache 区域,这意味着频繁在片外 RAM 访问的变量可以像在片上 RAM 中一样快速读取和修改。但访问大块数据时(大于 32 KBcache 空间可能会不足,访问速度将回落到片外 RAM 访问速度。此外,访问大块数据可以挤出 flash cache可能会降低代码执行速度。
* 片外 RAM 不可用作任务堆栈存储器。因此 :cpp:func:`xTaskCreate` 及类似函数将始终为堆栈和任务 TCB 分配片上储存器,而 :cpp:func:`xTaskCreateStatic` 类型的函数将检查传递的 Buffer 是否属于片上存储器。 * 片外 RAM 不可用作任务堆栈存储器。因此 :cpp:func:`xTaskCreate` 及类似函数将始终为堆栈和任务 TCB 分配片上储存器,而 :cpp:func:`xTaskCreateStatic` 类型的函数将检查传递的 Buffer 是否属于片上存储器。
@ -123,6 +121,6 @@ ESP-IDF 启动过程中,片外 RAM 被映射到以 0x3F800000 起始的数据
.. include:: inc/external-ram-esp32-notes.rst .. include:: inc/external-ram-esp32-notes.rst
.. _ESP32 ECO: https://www.espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_en.pdf .. _ESP32 ECO: https://www.espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_cn.pdf
.. _ESP32 ECO V3 User Guide: https://www.espressif.com/sites/default/files/documentation/ESP32_ECO_V3_User_Guide__EN.pdf .. _ESP32 ECO V3 User Guide: https://www.espressif.com/sites/default/files/documentation/ESP32_ECO_V3_User_Guide__CN.pdf

View File

@ -5,39 +5,39 @@ API 指南
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
一般注意事项 <general-notes> 应用层跟踪 <app_trace>
:SOC_BT_SUPPORTED: BluFi <blufi>
引导加载程序 <bootloader>
构建系统 <build-system> 构建系统 <build-system>
:esp32: 构建系统 (传统 GNU Make) <build-system-legacy> :esp32: 构建系统 (传统 GNU Make) <build-system-legacy>
深度睡眠唤醒存根 <deep-sleep-stub>
:esp32s2: 通过 USB 升级设备固件 <dfu>
错误处理 <error-handling> 错误处理 <error-handling>
严重错误 <fatal-errors>
Event Handling <event-handling>
Deep Sleep Wake Stubs <deep-sleep-stub>
:esp32s2: Device Firmware Upgrade through USB <dfu>
ESP32 Core Dump <core_dump>
Flash Encryption <../security/flash-encryption>
FreeRTOS SMP Changes <freertos-smp>
Thread Local Storage <thread-local-storage>
硬件抽象层 <hardware-abstraction>
:CONFIG_IDF_TARGET_ARCH_XTENSA: High Level Interrupts <hlinterrupts>
JTAG 调试 <jtag-debugging/index>
引导加载程序 <bootloader>
分区表 <partition-tables>
:esp32: Secure Boot <../security/secure-boot-v1>
Secure Boot V2 <../security/secure-boot-v2>
:SOC_ULP_SUPPORTED: ULP 协处理器 <ulp>
:esp32: ULP (传统 GNU Make) <ulp-legacy>
:esp32s2: ULP-RISC-V Coprocessor <ulp-risc-v>
单元测试 <unit-tests>
:esp32: 单元测试 (传统 GNU Make) <unit-tests-legacy>
应用层跟踪 <app_trace>
ROM debug console <romconsole>
:esp32: RF Calibration <RF_calibration>
WiFi Driver <wifi>
:SOC_BT_SUPPORTED: ESP-BLE-MESH <esp-ble-mesh/ble-mesh-index> :SOC_BT_SUPPORTED: ESP-BLE-MESH <esp-ble-mesh/ble-mesh-index>
ESP-MESH (Wi-Fi) <mesh> ESP-MESH (Wi-Fi) <mesh>
:SOC_BT_SUPPORTED: BluFi <blufi> 核心转储 <core_dump>
:SOC_SPIRAM_SUPPORTED: External SPI-connected RAM <external-ram> 事件处理 <event-handling>
:SOC_SPIRAM_SUPPORTED: 片外 SPI RAM <external-ram>
严重错误 <fatal-errors>
Flash 加密 <../security/flash-encryption>
FreeRTOS SMP 变化 <freertos-smp>
一般注意事项 <general-notes>
硬件抽象层 <hardware-abstraction>
:CONFIG_IDF_TARGET_ARCH_XTENSA: 高层中断 <hlinterrupts>
JTAG 调试 <jtag-debugging/index>
链接脚本生成机制 <linker-script-generation> 链接脚本生成机制 <linker-script-generation>
LwIP <lwip> lwIP TCP/IP 协议栈 <lwip>
Tools <tools/index> 分区表 <partition-tables>
:esp32s2: USB console <usb-console> :esp32: 射频校准 <RF_calibration>
ROM 调试控制台 <romconsole>
:esp32: 安全启动 <../security/secure-boot-v1>
安全启动 V2 <../security/secure-boot-v2>
线程本地存储 <thread-local-storage>
工具 <tools/index>
:SOC_ULP_SUPPORTED: ULP 协处理器 <ulp>
:esp32: ULP (传统 GNU Make) <ulp-legacy>
:esp32s2: ULP-RISC-V 协处理器 <ulp-risc-v>
单元测试 <unit-tests>
:esp32: 单元测试 (传统 GNU Make) <unit-tests-legacy>
:esp32s2: USB 控制台 <usb-console>
Wi-Fi 驱动 <wifi>

View File

@ -6,17 +6,17 @@ ULP 协处理器编程
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
:esp32: 指令集参考 <ulp_instruction_set> :esp32: ESP32 ULP 指令集参考 <ulp_instruction_set>
:esp32s2: 指令集参考 <ulps2_instruction_set> :esp32s2: ESP32-S2 ULP 指令集参考 <ulps2_instruction_set>
使用宏进行编程(遗留) <ulp_macros> 使用宏进行编程(遗留) <ulp_macros>
ULPUltra Low Power 超低功耗)协处理器是一种简单的有限状态机 (FSM),可以在主处理器处于深度睡眠模式时,使用 ADC、温度传感器和外部 I2C 传感器执行测量操作。ULP 协处理器可以访问 RTC_SLOW_MEM 内存区域及 RTC_CNTL、RTC_IO、SARADC 外设寄存器。ULP 协处理器使用 32 位固定宽度的指令32 位内存寻址,配备 4 个 16 位通用寄存器。 ULPUltra Low Power 超低功耗)协处理器是一种简单的有限状态机 (FSM),可以在主处理器处于深度睡眠模式时,使用 ADC、温度传感器和外部 I2C 传感器执行测量操作。ULP 协处理器可以访问 RTC_SLOW_MEM 内存区域及 RTC_CNTL、RTC_IO、SARADC 外设中的寄存器。ULP 协处理器使用 32 位固定宽度的指令32 位内存寻址,配备 4 个 16 位通用寄存器。
安装工具链 安装工具链
---------- ----------
ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp 工具链` 进行编译。 ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp 工具链`_ 进行编译。
如果你已经按照 :doc:`快速入门指南 <../../get-started/index>` 中的介绍安装好了 ESP-IDF 及其 CMake 构建系统,那么 ULP 工具链已经被默认安装到了你的开发环境中。 如果你已经按照 :doc:`快速入门指南 <../../get-started/index>` 中的介绍安装好了 ESP-IDF 及其 CMake 构建系统,那么 ULP 工具链已经被默认安装到了你的开发环境中。
@ -24,7 +24,6 @@ ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp
如果你的 ESP-IDF 仍在使用传统的基于 GNU Make 的构建系统,请参考 :doc:`ulp-legacy` 一文中的说明,完成工具链的安装。 如果你的 ESP-IDF 仍在使用传统的基于 GNU Make 的构建系统,请参考 :doc:`ulp-legacy` 一文中的说明,完成工具链的安装。
编译 ULP 代码 编译 ULP 代码
------------- -------------
@ -32,8 +31,7 @@ ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp
1. 用汇编语言编写的 ULP 代码必须导入到一个或多个 `.S` 扩展文件中,且这些文件必须放在组件目录中一个独立的目录中,例如 `ulp/` 1. 用汇编语言编写的 ULP 代码必须导入到一个或多个 `.S` 扩展文件中,且这些文件必须放在组件目录中一个独立的目录中,例如 `ulp/`
.. note: 在注册组件(通过 ``idf_component_register``)时,不应将该目录添加到 ``SRC_DIRS`` 参数中。因为 ESP-IDF 构建系统将基于文件扩展名编译在 ``SRC_DIRS`` 中搜索到的文件。对于 ``.S`` 文件,使用的是 ``xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf-as`` 汇编器。但这并不适用于 ULP 程序集文件,因此体现这种区别最简单的方式就是将 ULP 程序集文件放到单独的目录中。同样ULP 程序集源文件也 **不应该** 添加到 ``SRCS`` 中。请参考如下步骤,查看如何正确添加 ULP 程序集源文件。 .. note: 在(通过 ``idf_component_register``)注册组件时,不应将该目录添加到 ``SRC_DIRS`` 参数中。因为 ESP-IDF 构建系统将基于文件扩展名编译在 ``SRC_DIRS`` 中搜索到的文件。对于 ``.S`` 文件,使用的是 ``xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf-as`` 汇编器。但这并不适用于 ULP 程序集文件,因此体现这种区别最简单的方式就是将 ULP 程序集文件放到单独的目录中。同样ULP 程序集源文件也 **不应该** 添加到 ``SRCS`` 中。请参考如下步骤,查看如何正确添加 ULP 程序集源文件。
2. 注册后从组件 CMakeLists.txt 中调用 ``ulp_embed_binary`` 示例如下:: 2. 注册后从组件 CMakeLists.txt 中调用 ``ulp_embed_binary`` 示例如下::
@ -46,7 +44,7 @@ ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp
ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}") ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}")
上述第一个参数到 ``ulp_embed_binary`` 为 ULP 二进制文件命名。此名称也用于生成的其他文件ELF 文件、.map 文件、头文件和链接器导出文件。第二个参数设置 ULP 程序集源文件。最后,第三个参数设置组件源文件列表,其中包括被生成的头文件。此列表用以建立正确的依赖项,并确保在构建过程会先生成再编译包含头文件的源文件。请参考下文,查看为 ULP 应用程序生成的头文件等相关概念。 ``ulp_embed_binary`` 的第一个参数为 ULP 二进制文件命名。指定的此名称也用于生成的其他文件ELF 文件、.map 文件、头文件和链接器导出文件。第二个参数指定 ULP 程序集源文件。最后,第三个参数指定组件源文件列表,其中包括被生成的头文件。此列表用以建立正确的依赖项,并确保在编译这些文件之前先创建生成的头文件。有关 ULP 应用程序生成的头文件等相关概念,请参考下文
3. 使用常规方法(例如 `idf.py app`)编译应用程序 3. 使用常规方法(例如 `idf.py app`)编译应用程序
@ -82,7 +80,7 @@ ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp
move r3, measurement_count move r3, measurement_count
ld r3, r3, 0 ld r3, r3, 0
主程序需要在启动 ULP 程序之前初始化 ``measurement_count`` 变量,构建系统生成定义 ULP 编程中全局符号的 ``${ULP_APP_NAME}.h````${ULP_APP_NAME}.ld`` 文件,可以实现上述操作,这些文件包含在 ULP 程序中定义的所有全局符号,文件以 ``ulp_`` 开头。 主程序需要在启动 ULP 程序之前初始化 ``measurement_count`` 变量,构建系统通过生成定义 ULP 编程中全局符号的 ``${ULP_APP_NAME}.h````${ULP_APP_NAME}.ld`` 文件实现上述操作。这些文件包含了在 ULP 程序中定义的所有全局符号,文件以 ``ulp_`` 开头。
头文件包含对此类符号的声明:: 头文件包含对此类符号的声明::
@ -143,21 +141,40 @@ ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp
entry: entry:
/* code starts here */ /* code starts here */
.. only:: esp32
ULP 程序流 ESP32 ULP 程序流
---------- ------------------
ULP 协处理器由定时器启动,而调用 ``ulp_run`` 则可启动此定时器。定时器为 RTC_SLOW_CLK 的 Tick 事件计数默认情况下Tick 由内部 150 KHz 晶振器生成)。使用 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器 (x = 0..4) 设置 Tick 数值。第一次启动 ULP 时,使用 ``SENS_ULP_CP_SLEEP_CYC0_REG`` 设置定时器 Tick 数值之后ULP 程序可以使用 ``sleep`` 指令来另外选择 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器。 ESP32 ULP 协处理器由定时器启动,而调用 ``ulp_run`` 则可启动此定时器。定时器为 RTC_SLOW_CLK 的 Tick 事件计数默认情况下Tick 由内部 150 KHz RC 振荡器生成)。使用 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器 (x = 0..4) 设置 Tick 数值。第一次启动 ULP 时,使用 ``SENS_ULP_CP_SLEEP_CYC0_REG`` 设置定时器 Tick 数值之后ULP 程序可以使用 ``sleep`` 指令来选择另一个 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器。
此应用程序可以调用 ``ulp_set_wakeup_period`` 函数来设置 ULP 定时器周期值 (SENS_ULP_CP_SLEEP_CYCx_REG, x = 0..4)。 此应用程序可以调用 ``ulp_set_wakeup_period`` 函数来设置 ULP 定时器周期值 (SENS_ULP_CP_SLEEP_CYCx_REG, x = 0..4)。
.. doxygenfunction:: ulp_set_wakeup_period .. doxygenfunction:: ulp_set_wakeup_period
一旦定时器为所选的 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器的 Tick 事件计ULP 协处理器就会启动,并调用 ``ulp_run`` 的入口点开始运行程序。 一旦定时器计数到 ``SENS_ULP_CP_SLEEP_CYCx_REG`` 寄存器设定的 Tick 数ULP 协处理器就会启动,并调用 ``ulp_run`` 的入口点开始运行程序。
程序保持运行,直到遇到 ``halt`` 指令或非法指令。一旦程序停止ULP 协处理器电源关闭,定时器再次启动。 程序保持运行,直到遇到 ``halt`` 指令或非法指令。一旦程序停止ULP 协处理器电源关闭,定时器再次启动。
如果想禁用定时器(有效防止 ULP 程序再次运行),请清除 ``RTC_CNTL_STATE0_REG`` 寄存器中的 ``RTC_CNTL_ULP_CP_SLP_TIMER_EN`` 位,可在 ULP 代码或主程序中进行以上操作。 如果想禁用定时器(有效防止 ULP 程序再次运行),可在 ULP 代码或主程序中清除 ``RTC_CNTL_STATE0_REG`` 寄存器中的 ``RTC_CNTL_ULP_CP_SLP_TIMER_EN`` 位。
.. only:: esp32s2
ESP32-S2 ULP 程序流
--------------------
ESP32-S2 ULP 协处理器由定时器启动,调用 ``ulp_run`` 则可启动此定时器。定时器为 RTC_SLOW_CLK 的 Tick 事件计数默认情况下Tick 由内部 90 KHz RC 振荡器生成)。使用 ``RTC_CNTL_ULP_CP_TIMER_1_REG`` 寄存器设置 Tick 数值。
此应用程序可以调用 ``ulp_set_wakeup_period`` 函数来设置 ULP 定时器周期值。
.. doxygenfunction:: ulp_set_wakeup_period
一旦定时器计数到 ``RTC_CNTL_ULP_CP_TIMER_1_REG`` 寄存器设定的 Tick 数值ULP 协处理器就会启动,并调用 ``ulp_run`` 的入口点开始运行程序。
程序保持运行,直到遇到 ``halt`` 指令或非法指令。一旦程序停止ULP 协处理器电源关闭,定时器再次启动。
如果想禁用定时器(有效防止 ULP 程序再次运行),可在 ULP 代码或主程序中清除 ``RTC_CNTL_STATE0_REG`` 寄存器中的 ``RTC_CNTL_ULP_CP_SLP_TIMER_EN`` 位。
.. _binutils-esp32ulp 工具链: https://github.com/espressif/binutils-esp32ulp .. _binutils-esp32ulp 工具链: https://github.com/espressif/binutils-esp32ulp