ハードウェア
利用するボードによって、SPI制御に使うピンの指定を変更する必要がある。。
- Espressif ESP32 開発用ボード
- Micro SD カード 用 シールド
- WeMos Dual Base ver.1
- 新しい ver 2.0 の Dual Base を利用すると MH-ET Live ESP32 Minikit と WeMos Micro SD Card Shield が干渉してしまう。その場合には、WeMos Tripler Base などを利用する必要がある。
- Micro SD カード
- Toshiba 16GB M203
開発環境
- Windows10
- PlatformIO IDE for Visual Studio Code
- ESP-IDF フレームワークを利用
PlatformIO IDE for Visual Studio Code を利用した ESP32 用開発については、PlatformIO IDE for VSCode でESP32のプログラム開発 の設定を参照のこと。
プログラム
次にある、ESP-IDFのSDカード制御のサンプルプログラムを修正した。
https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card
16kiBのデータの書き込みに要した時間を計測する。1万回繰り返し、それから書き込み時間の平均値、最悪値を求め、それらから書き込み速度を求める単純なプログラムである。
次のGitHubに、Platform IDE for VSCodeでの開発用ファイルを置いてある。
https://github.com/kunsen-an/espidf_sd_card_write_test.git
実行結果例
ある時点での実行結果は以下のようであった。1万回実行しているので150秒以上かかっている。
平均的には1MB/s以上で書き込みが可能であるが、この例での最悪値は、約21kB/s であった。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0018,len:4 load:0x3fff001c,len:4952 load:0x40078000,len:7760 ho 0 tail 12 room 4 load:0x40080000,len:5892 entry 0x40080318 I (30) boot: ESP-IDF 3.30100.0 2nd stage bootloader I (30) boot: compile time 16:09:50 I (30) boot: Enabling RNG early entropy source... I (32) boot: SPI Speed : 40MHz I (35) boot: SPI Mode : DIO I (38) boot: SPI Flash Size : 4MB I (42) boot: Partition Table: I (44) boot: ## Label Usage Type ST Offset Length I (51) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (57) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (64) boot: 2 factory factory app 00 00 00010000 00100000 I (70) boot: End of partition table I (73) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x08cb4 ( 36020) map I (94) esp_image: segment 1: paddr=0x00018cdc vaddr=0x3ffc0000 size=0x01fd8 ( 8152) load I (97) esp_image: segment 2: paddr=0x0001acbc vaddr=0x3ffc1fd8 size=0x00000 ( 0) load I (99) esp_image: segment 3: paddr=0x0001acc4 vaddr=0x40080000 size=0x00400 ( 1024) load I (108) esp_image: segment 4: paddr=0x0001b0cc vaddr=0x40080400 size=0x04f44 ( 20292) load I (123) esp_image: segment 5: paddr=0x00020018 vaddr=0x400d0018 size=0x18f7c (102268) map I (160) esp_image: segment 6: paddr=0x00038f9c vaddr=0x40085344 size=0x03328 ( 13096) load I (165) esp_image: segment 7: paddr=0x0003c2cc vaddr=0x400c0000 size=0x00000 ( 0) load I (165) esp_image: segment 8: paddr=0x0003c2d4 vaddr=0x50000000 size=0x00000 ( 0) load I (178) boot: Loaded app from partition at offset 0x10000 I (178) boot: Disabling RNG early entropy source... I (183) cpu_start: Pro cpu up. I (185) cpu_start: Starting app cpu, entry point is 0x40081828 I (0) cpu_start: App cpu up. I (194) heap_init: Initializing. RAM available for dynamic allocation: I (199) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM I (204) heap_init: At 3FFDA938 len 000056C8 (21 KiB): DRAM I (210) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM I (215) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (220) heap_init: At 4008866C len 00017994 (94 KiB): IRAM I (226) cpu_start: Pro cpu start user code I (243) cpu_start: Starting scheduler on PRO CPU. I (0) cpu_start: Starting scheduler on APP CPU. I (244) example: Initializing SD card I (244) example: Using SPI peripheral I (244) gpio: GPIO[5]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 Name: SA16G Type: SDHC/SDXC Speed: default speed Size: 14832MB CSD: ver=1, sector_size=512, capacity=30375936 read_bl_len=9 SCR: sd_spec=2, bus_width=5 I (304) example: Opening file I (155204) example: File written write buffer size = 16384 sum=154883085 microseconds, average=15488 microseconds maximum=757276 microseconds, minimum=14308 microseconds highest write speed = 1145093 byte/s average write speed = 1057851 byte/s lowest write speed = 21635 byte/s I (155424) example: Renaming file I (155434) example: Reading file I (155434) example: Read from file: ' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^' I (155434) gpio: GPIO[23]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (155444) gpio: GPIO[19]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (155454) gpio: GPIO[18]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (155454) example: Card unmounted |
バッファの大きさ
録音データを連続して書き込む場合にはバッファを十分に用意しておかないと、バッファがオーバーフローする。最悪の書き込み速度が16kB/sと仮定し、 192kB/s 程度で連続して書き込みを行うなら12ブロック以上のバッファを用意しておかないとデータが失われる可能性がある。プログラムでは16kiB/ブロックなので、192KiB以上のバッファが必要であろう。