Jiang Guang Ming 947c112233 Merge branch 'bugfix/update_esp_rom_gpio_header' into 'master' %!s(int64=3) %!d(string=hai) anos
..
esp32 08fd77a09a move {target}/rom/miniz.h to a common miniz.h %!s(int64=3) %!d(string=hai) anos
esp32c2 97d6050fea Merge branch 'feature/esp32c2_optimize_npl_element_count' into 'master' %!s(int64=3) %!d(string=hai) anos
esp32c3 1c96b509bb esp_wifi: fix multicast pkts drop issue for some AP when DTIM period > 1 %!s(int64=3) %!d(string=hai) anos
esp32c6 182e937c5a clk_tree: Add basic clock support for esp32c6 %!s(int64=3) %!d(string=hai) anos
esp32h2 7db7269a92 esp_rom: patch systimer_hal_init/deinit for esp32h2 rom %!s(int64=3) %!d(string=hai) anos
esp32h4 08fd77a09a move {target}/rom/miniz.h to a common miniz.h %!s(int64=3) %!d(string=hai) anos
esp32s2 66a0cedf5a esp_rom: add ESP_ROM_HAS_REGI2C_BUG in rom caps %!s(int64=3) %!d(string=hai) anos
esp32s3 1c96b509bb esp_wifi: fix multicast pkts drop issue for some AP when DTIM period > 1 %!s(int64=3) %!d(string=hai) anos
host_test 44aa3c3a7f bugfix(esp_rom): Fixed writable string issue on Linux implementation %!s(int64=3) %!d(string=hai) anos
include 7c0c5481c8 esp_rom: update rom gpio.h %!s(int64=3) %!d(string=hai) anos
linux 44aa3c3a7f bugfix(esp_rom): Fixed writable string issue on Linux implementation %!s(int64=3) %!d(string=hai) anos
patches bec679fbc6 Merge branch 'bugfix/fix_esp32c6_regi2c_enable_clock' into 'master' %!s(int64=3) %!d(string=hai) anos
test_apps 7466ddfa8c ci: Make consistence between pytest_*.py and .build-test-rules.yml for esp32c6 (i.e. to pass check_test_scripts_build_test_rules.py) %!s(int64=3) %!d(string=hai) anos
.build-test-rules.yml 65767769a9 esp_rom: migrate ut to pytest %!s(int64=3) %!d(string=hai) anos
CMakeLists.txt 454aeb3a48 Merge branch 'feature/add_new_caps_for_rom_has_regi2c_bug' into 'master' %!s(int64=3) %!d(string=hai) anos
Kconfig.projbuild c6d60615c6 build-system: include soc_caps defines into kconfig %!s(int64=4) %!d(string=hai) anos
README.md 8677216576 esp32h2: renaming esp32h2 to esp32h4 %!s(int64=3) %!d(string=hai) anos
linker.lf 0d5fe4d1c3 esp_rom: put regi2c override apis to IRAM %!s(int64=3) %!d(string=hai) anos

README.md

esp_rom Component

Function Description

esp_rom component contains each chip's ROM functions, which are used in the ROM bootloader, 2nd bootloader, esp_tool flash stub and some driver code (e.g. GPIO matrix). ROM functions as not treated as public APIs, attentions are required when you use ROM functions:

  1. ROM functions are not thread-safe in RTOS, extra locks are needed to be around the ROM functions.
  2. Names/signatures/behaviors of ROM function may be different between chips.
  3. ROM functions are not guaranteed to exist across all chips.

When using ROM functions in esp-idf, the including convention is <target>/rom/<header_file>.h. This can prevent you from using a nonexistent ROM function for a specific <target>. Thus ROM functions are recommended for use in a target-specific source file. For example, bootloader_esp32.c can include esp32/rom/<header_file>.h without any violations. However, this is not the case when it comes to a common source file that also wants to use some of the ROM functions. The include list would be quite extensive:

#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/uart.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/uart.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/uart.h"
#elif CONFIG_IDF_TARGET_ESP32H4
#include "esp32h4/rom/uart.h"
...

So, we added a wrapper for those commonly used ROM functions. They're declared in esp_rom/include/esp_rom_xxx.h. Unlike the original ROM functions, these extracted ones are expected to exist across all chips. If some of them are missed in the new chips, we will implement them again in esp_rom/patches. These ROM APIs are always prefixed with the name esp_rom (e.g. esp_rom_printf), so that it's obvious to know whether a function is linked to ROM.

Most of the time, the ROM wrapper APIs are just alias to the original ROM functions by linker script esp_rom/<target>/ld/<target>.rom.api.ld. For example, esp_rom_printf is alias to ets_printf in the following way:

PROVIDE ( esp_rom_printf = ets_printf );

If some original ROM functions have changed the behavior or have bugs, we should override them in the wrapper layer. A common example is the esp_rom_install_uart_printf(), on ESP32 and ESP32S2, it's just alias to ets_install_uart_printf, but on other chips, it's re-implemented in the esp_rom/patches/esp_rom_uart.c. To some extent, the ROM wrapper layer works like an anti-corrosion layer between esp-rom project and esp-idf project.

As ROM functions are unique to each target, features are as well. For example, ESP32 has the tjpgd library built into the ROM, but ESP32S2 hasn't. We have a header file esp_rom/<target>/esp_rom_caps.h declaring the features that are supported by each target. Based on the macros defined there, we can decide whether a function should be patched or whether a feature should be re-implemented.

Directory Structure

.
├── CMakeLists.txt
├── <target/chip_name>
│   ├── esp_rom_caps.h
│   └── ld
│       ├── <target>.rom.api.ld
│       ├── <target>.rom.ld
│       ├── <target>.rom.libgcc.ld
│       ├── <target>.rom.newlib.ld
│       ├── <target>.rom.newlib-nano.ld
│       ├── <target>.rom.version.ld
│       └── ... // other ROM linker scripts, added when bring up new chip
├── include
│   ├── <target/chip_name>
│   │   └── rom
│   │       ├── cache.h
│   │       ├── efuse.h
│   │       ├── esp_flash.h
│   │       ├── ets_sys.h
│   │       ├── gpio.h
│   │       ├── uart.h
│   │       └── ... // other original ROM header files, added when bring up new chip
│   ├── esp_rom_gpio.h
│   ├── esp_rom_md5.h
│   ├── esp_rom_sys.h
│   ├── esp_rom_uart.h
│   └── ... // other ROM wrapper api files
├── Kconfig.projbuild
├── linker.lf
├── patches
│   ├── esp_rom_sys.c
│   ├── esp_rom_uart.c
│   └── ... // other patched source files
├── README.md
└── test
    ├── CMakeLists.txt
    ├── test_miniz.c
    └── ... // other ROM function unit tests