ESP-IDFを使ってみる

ROM Component


ESP-IDFにはUndocumentな機能が沢山有ります。
Tiny JPEG Decompressorを使うためには以下のヘッダーファイルをincludeする必要が有ります。
#include "rom/tjpgd.h"

このファイルはcomponents/esp_rom/include/esp32/romの下にありますが、
このディレクトリには他にも面白そうなヘッダーファイルや、 使い方が分からないヘッダーファイルがいくつかあります。
$ ls esp-idf/components/esp_rom/include/esp32/rom
aes.h     efuse.h       lldesc.h    rtc.h          tbconsole.h
bigint.h  ets_sys.h     md5_hash.h  secure_boot.h  tjpgd.h
cache.h   gpio.h        miniz.h     sha.h          uart.h
crc.h     libc_stubs.h  rsa_pss.h   spi_flash.h

aes.h
AES(Advanced Encryption Standard)と呼ばれる暗号化方式のうち、256ビット長の暗号鍵を使用する方式。

crc.h
crc8、crc16-CCITT、crc32計算ライブラリ。

gpio.h
gpio_pad_select_gpio()などの低レベルgoioライブラリ。

md5_hash.h
暗号学的ハッシュ関数のひとつ。

miniz.h
zlib(RFC 1950)およびDeflate(RFC 1951)圧縮データ形式仕様標準を実装する、シングルソースファイルのロスレス高性能データ圧縮ライブラリ。

sha.h
SHA(Secure Hash Algorithm)によるハッシュ値計算ライブラリ。

tbconsole.h
Tiny Basic
IO12をプルアップしてESP32を起動するとBASICが実行できます。



components/esp_rom/include/esp32/romの内容はビルド時にESP32のROMに置かれます。
ESP32-S2はROMサイズが小さいので、ESP32に比べファイルが少なくなっていますが、逆にUSBのデイレクトリが増えています。
$ ls esp-idf/components/esp_rom/include/esp32s2/rom
aes.h     digital_signature.h  hmac.h        miniz.h      secure_boot.h  usb
bigint.h  efuse.h              libc_stubs.h  opi_flash.h  sha.h
cache.h   ets_sys.h            lldesc.h      rsa_pss.h    spi_flash.h
crc.h     gpio.h               md5_hash.h    rtc.h        uart.h

ESP32-S3はこのようになります。
ESP32-S2よりもROMサイズが大きいので、tjpeg.hが復活しています。
$ ls esp-idf/components/esp_rom/include/esp32s3/rom
aes.h             digital_signature.h  libc_stubs.h  rom_layout.h   spi_flash.h
apb_backup_dma.h  efuse.h              lldesc.h      rsa_pss.h      tjpgd.h
bigint.h          ets_sys.h            md5_hash.h    rtc.h          uart.h
cache.h           gpio.h               miniz.h       secure_boot.h  usb
crc.h             hmac.h               opi_flash.h   sha.h

ESP32-C3はこのようになります。
$ ls esp-idf/components/esp_rom/include/esp32c3/rom
aes.h             digital_signature.h  hmac.h        rom_layout.h   spi_flash.h
apb_backup_dma.h  efuse.h              libc_stubs.h  rsa_pss.h      tjpgd.h
bigint.h          esp_flash.h          lldesc.h      rtc.h          uart.h
cache.h           ets_sys.h            md5_hash.h    secure_boot.h
crc.h             gpio.h               miniz.h       sha.h

ESP32-H2はこのようになります。
$ ls esp-idf/components/esp_rom/include/esp32h2/rom
aes.h             digital_signature.h  hmac.h        rom_layout.h   spi_flash.h
apb_backup_dma.h  efuse.h              libc_stubs.h  rsa_pss.h      tjpgd.h
bigint.h          esp_flash.h          lldesc.h      rtc.h          uart.h
cache.h           ets_sys.h            md5_hash.h    secure_boot.h
crc.h             gpio.h               miniz.h       sha.h



components/esp_rom/include/esp32/romの内容はビルド時にESP32のROMに置かれます。
SoCによってROMに含まれる内容が異なります。
ESP-IDF Ver5から、どのコンポーネントがROMに含まれているか、アプリで判定できるようになりました。
以下のコードで判定することができます。
#include "esp_rom_caps.h"

#if defined(ESP_ROM_HAS_JPEG_DECODE)
#include "rom/tjpgd.h"
#else
#error Using JPEG decoder from ROM is not supported for selected target.
#endif

void app_main()
{
}

上記のコードをビルドするとesp32では問題なくビルドできますが、esp32s2では以下のエラーとなります。
   11 | #error Using JPEG decoder from ROM is not supported for selected target.
      |  ^~~~~

esp_rom_caps.hはSoCごとに存在するファイルで、esp32の場合、以下の内容になっています。
$ cat esp-idf/components/esp_rom/esp32/esp_rom_caps.h
/*
 * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#define ESP_ROM_HAS_CRC_LE              (1) // ROM CRC library supports Little Endian
#define ESP_ROM_HAS_CRC_BE              (1) // ROM CRC library supports Big Endian
#define ESP_ROM_HAS_JPEG_DECODE         (1) // ROM has JPEG decode library
#define ESP_ROM_SUPPORT_MULTIPLE_UART   (1) // ROM has multiple UARTs available for logging
#define ESP_ROM_NEEDS_SWSETUP_WORKAROUND    (1) // ROM uses 32-bit time_t. A workaround is required to prevent printf functions from crashing

esp32s2の場合、以下の内容になっています。
ESP_ROM_HAS_CRC_BE と ESP_ROM_HAS_JPEG_DECODE が定義されていません。
$ cat esp-idf/components/esp_rom/esp32s2/esp_rom_caps.h
/*
 * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#define ESP_ROM_HAS_CRC_LE            (1) // ROM CRC library supports Little Endian
#define ESP_ROM_SUPPORT_MULTIPLE_UART (1) // ROM has multiple UARTs available for logging
#define ESP_ROM_NEEDS_SWSETUP_WORKAROUND    (1) // ROM uses 32-bit time_t. A workaround is required to prevent printf functions from crashing



ROM Componentに関する記述がこ ちらに公開されています。
この様な注意が書かれています。
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.

1. ROM 関数は RTOS ではスレッドセーフではありません。ROM 関数については追加のロックが必要です。
2. ROM 機能の名前/シグネチャ/動作は、チップ間で異なる場合があります。
3. ROM 機能は、すべてのチップで存在することを保証するものではありません。

続く...