ESP-IDFを使ってみる

External SPI FLASH Memory


ESP32シリーズのモジュールはCPUとSPI FLASH Memoryから構成されています。
また、ESP32Cシリーズの一部はコア内部にSPI FLASH Memoryを持っています。
ESP-IDFではSPI FLASH Memoryをファイルシステムとして利用することができますが、
こ ちらにExternal SPI FLASH Memory上にFATファイルシステムを構築するサンプルが公開されています。
ESP32のオンボードFLASHは4MByteで、オンボードFLASH上に最大約3MByteのストレージを確保することができますが、
大容量のSPI FLASH Memoryを使えば、大容量のストレージを追加することができます。
SPI FLASH Memoryとの接続は以下の通りです。

# SPI FLASH Memory ESP32
1 /CS GPIO5
2 DO GPIO19
3 /WP 3.3V
4 GND GND
5 DI GPIO23
6 CLK GPIO18
7 /HOLD 3.3V
8 VCC 3.3V

WinbondのW25Q64を使って試してみました。
SPI FLASHをFATでマウントし、「Written using ESP-IDF v4.2-dev-701-g0ae960f2f-dirty」の文字を書き込んでいます。
JEDEC-IDとして正しい値「0xef4017」が取れて、8192KB(8MByte)の領域が追加されます。
I (0) cpu_start: Starting scheduler on APP CPU.
I (328) example: Initializing external SPI Flash
I (338) example: Pin assignments:
I (338) example: MOSI: 23   MISO: 19   SCLK: 18   CS:  5
I (348) spi_flash: detected chip: generic
I (348) spi_flash: flash io: dio
I (368) example: Initialized external Flash, size=8192 KB, ID=0xef4017
I (368) example: Adding external Flash as a partition, label="storage", size=8192 KB
I (368) example: Listing data partitions:
I (378) example: - partition 'nvs', subtype 2, offset 0x9000, size 24 kB
I (378) example: - partition 'phy_init', subtype 1, offset 0xf000, size 4 kB
I (388) example: - partition 'storage', subtype 129, offset 0x0, size 8192 kB
I (398) example: Mounting FAT filesystem
W (1408) vfs_fat_spiflash: f_mount failed (13)
I (1408) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=4096
I (2118) vfs_fat_spiflash: Mounting again
I (2128) example: FAT FS: 8088 kB total, 8088 kB free
I (2128) example: Opening file
I (2598) example: File written
I (2598) example: Reading file
I (2608) example: Read from file: 'Written using ESP-IDF v4.2-dev-701-g0ae960f2f-dirty'

WinbondのW25Q128だと16386KB(16MByte)の領域を確保することができます。
I (0) cpu_start: Starting scheduler on APP CPU.
I (328) example: Initializing external SPI Flash
I (338) example: Pin assignments:
I (338) example: MOSI: 23   MISO: 19   SCLK: 18   CS:  5
I (348) spi_flash: detected chip: generic
I (348) spi_flash: flash io: dio
I (368) example: Initialized external Flash, size=16384 KB, ID=0xef4018
I (368) example: Adding external Flash as a partition, label="storage", size=16384 KB
I (368) example: Listing data partitions:
I (378) example: - partition 'nvs', subtype 2, offset 0x9000, size 24 kB
I (378) example: - partition 'phy_init', subtype 1, offset 0xf000, size 4 kB
I (388) example: - partition 'storage', subtype 129, offset 0x0, size 16384 kB
I (398) example: Mounting FAT filesystem
W (3458) vfs_fat_spiflash: f_mount failed (13)
I (3458) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=4096
I (4528) vfs_fat_spiflash: Mounting again
I (4538) example: FAT FS: 16212 kB total, 16212 kB free
I (4538) example: Opening file
I (5148) example: File written
I (5148) example: Reading file
I (5148) example: Read from file: 'Written using ESP-IDF v4.2-dev-701-g0ae960f2f-dirty'

MacronixのMX25L6473Eでも試してみました。
こちらも問題なく動きます。
I (0) cpu_start: Starting scheduler on APP CPU.
I (328) example: Initializing external SPI Flash
I (338) example: Pin assignments:
I (338) example: MOSI: 23   MISO: 19   SCLK: 18   CS:  5
I (348) spi_flash: detected chip: generic
I (348) spi_flash: flash io: dio
I (358) example: Initialized external Flash, size=8192 KB, ID=0xc22017
I (358) example: Adding external Flash as a partition, label="storage", size=8192 KB
I (368) example: Listing data partitions:
I (368) example: - partition 'nvs', subtype 2, offset 0x9000, size 24 kB
I (378) example: - partition 'phy_init', subtype 1, offset 0xf000, size 4 kB
I (388) example: - partition 'storage', subtype 129, offset 0x0, size 8192 kB
I (398) example: Mounting FAT filesystem
W (868) vfs_fat_spiflash: f_mount failed (13)
I (868) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=4096
I (1428) vfs_fat_spiflash: Mounting again
I (1428) example: FAT FS: 8088 kB total, 8088 kB free
I (1428) example: Opening file
I (1798) example: File written
I (1798) example: Reading file
I (1798) example: Read from file: 'Written using ESP-IDF v4.2-dev-701-g0ae960f2f-dirty'

MacronixのMX25L12835Fも問題なく動きます。
I (0) cpu_start: Starting scheduler on APP CPU.
I (328) example: Initializing external SPI Flash
I (338) example: Pin assignments:
I (338) example: MOSI: 23   MISO: 19   SCLK: 18   CS:  5
I (348) spi_flash: detected chip: generic
I (348) spi_flash: flash io: dio
I (348) example: Initialized external Flash, size=16384 KB, ID=0xc22018
I (358) example: Adding external Flash as a partition, label="storage", size=16384 KB
I (368) example: Listing data partitions:
I (368) example: - partition 'nvs', subtype 2, offset 0x9000, size 24 kB
I (378) example: - partition 'phy_init', subtype 1, offset 0xf000, size 4 kB
I (388) example: - partition 'storage', subtype 129, offset 0x0, size 16384 kB
I (398) example: Mounting FAT filesystem
W (1428) vfs_fat_spiflash: f_mount failed (13)
I (1428) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=4096
I (2108) vfs_fat_spiflash: Mounting again
I (2108) example: FAT FS: 16212 kB total, 16212 kB free
I (2108) example: Opening file
I (2488) example: File written
I (2488) example: Reading file
I (2488) example: Read from file: 'Written using ESP-IDF v4.2-dev-701-g0ae960f2f-dirty'

GigaDeviceのGD25Q64では、JEDEC-IDは取得できますが、マウントすることができませんでした。
I (0) cpu_start: Starting scheduler on APP CPU.
I (329) example: Initializing external SPI Flash
I (339) example: Pin assignments:
I (339) example: MOSI: 23   MISO: 19   SCLK: 18   CS:  5
I (349) spi_flash: detected chip: gd
I (349) spi_flash: flash io: dio
I (349) example: Initialized external Flash, size=8192 KB, ID=0xc84017
I (359) example: Adding external Flash as a partition, label="storage", size=8192 KB
I (369) example: Listing data partitions:
I (369) example: - partition 'nvs', subtype 2, offset 0x9000, size 24 kB
I (379) example: - partition 'phy_init', subtype 1, offset 0xf000, size 4 kB
I (389) example: - partition 'storage', subtype 129, offset 0x0, size 8192 kB
I (399) example: Mounting FAT filesystem
W (399) vfs_fat_spiflash: f_mount failed (13)
I (409) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=4096
I (429) vfs_fat_spiflash: Mounting again
assertion "res == FR_OK" failed: file "/home/nop/esp-idf/examples/storage/ext_flash_fatfs/main/ext_flash_fatfs_example_main.c", line 181, function: example_get_fatfs_usage
abort() was called at PC 0x400d2dd3 on core 0
0x400d2dd3: __assert_func at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/newlib/newlib/libc/stdlib/assert.c:62 (discriminator 8)



FATファイルシステムなので、ディレクトリを作成することができます。
また、ファイル名は大文字小文字を区別しません。
以下の様にhello.txtのファイルを作成しても、ファイル名は大文字で扱われます。




WinbondのW25Q64を使ったベンチマークです。
読み書きのスピードはFatFsと同程度です。
ファイルシステム バイトセクター モード 書き込みスピード 読み込みスピード
FatFS 512 Safety 2 kB/s 590 kB/s
FatFS 512 Performance 7 kB/s 590 kB/s
FatFS 4096
60 kB/s 722 kB/s
SPIFFS

35 kB/s 406 kB/s
LittleFs

103 kB/s 650 kB/s
External-FatFS

50 kB/s 722 kB/s

W25Q64の最大クロックスピードは104MHzですが、このサンプルでは40MHzが使われます。
これ以上のクロックスピードを指定すると、Flash clock frequency round down to 1の警告が表示されます。


このサンプルの中で、パーティションの一覧を取り出すコードが使われています。
ESP-IDFのサンプルの中には、時々このような汎用的なコードが出現します。
以下のコードで定義されているパーテイションの一覧を取り出すことができます。
static void example_list_data_partitions(void)
{
    ESP_LOGI(TAG, "Listing data partitions:");
    esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL);

    for (; it != NULL; it = esp_partition_next(it)) {
        const esp_partition_t *part = esp_partition_get(it);
        ESP_LOGI(TAG, "- partition '%s', subtype %d, offset 0x%" PRIx32 ", size %" PRIu32 " kB",
        part->label, part->subtype, part->address, part->size / 1024);
    }

    esp_partition_iterator_release(it);
}

この関数を実行すると標準出力にはこのように表示されます。
I (20645) example: Listing data partitions:
I (20645) example: - partition 'nvs', subtype 2, offset 0x9000, size 24 kB
I (20645) example: - partition 'phy_init', subtype 1, offset 0xf000, size 4 kB
I (20645) example: - partition 'storage', subtype 129, offset 0x0, size 8192 kB

SPI FLASHは一般的にアドレスを指定して読み書きします。
シリアルデバイスとして利用するライブラリをこちらで公開していま す。

続く...