ESP32+MicroPythonでプログラムしているが、CMOSカメラで画像取得等をするとヒープメモリがすぐに枯渇する。組み込みプログラムではメモリとの闘いなのだが、十分なメモリ空間が簡単に手に入る、ESP32 WROVERだったらどうなのか。。と。ESP32 WROVERはPSRAMが内蔵されたバージョンで、メモリサイズは以下
・SRAM:520KB
・PSRAM:8MB
ファームを焼いていない状態でのブートメッセージ
ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0x00 clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3ffc0000,len:0 load:0x3ffc0000,len:2304 load:0x40078000,len:3788 ho 0 tail 12 room 4 load:0x40098000,len:532 entry 0x4009813c ************************************** * hello espressif ESP32! * * 2nd boot is running! * * version (V0.1) * ************************************** compile time 18:16:58 SPI Speed : 40MHz SPI Mode : DIO SPI Flash Size : 4MB Partition Table: ## Label Usage Type ST Offset Length 0 factory factory app 00 00 00010000 00100000 1 rfdata RF data 01 01 00110000 00040000 2 wifidata WiFi data 01 02 00150000 00040000 End of partition table Loading app partition at offset 00010000 section 0: paddr=0x00000020 vaddr=0x00000000 size=0x0ffe8 ( 65512) section 1: paddr=0x00010010 vaddr=0x3f400010 size=0x05b64 ( 23396) map section 2: paddr=0x00015b7c vaddr=0x3ffba720 size=0x01378 ( 4984) load section 3: paddr=0x00016efc vaddr=0x40080000 size=0x00400 ( 1024) load section 4: paddr=0x00017304 vaddr=0x40080400 size=0x126ac ( 75436) load section 5: paddr=0x000299b8 vaddr=0x00000000 size=0x06658 ( 26200) section 6: paddr=0x00030018 vaddr=0x400d0018 size=0x325b4 (206260) map start: 0x400807ac Initializing heap allocator: Region 19: 3FFBBA98 len 00024568 tag 0 Region 25: 3FFE8000 len 00018000 tag 1 Pro cpu up. Pro cpu start user code nvs_flash_init frc2_timer_task_hdl:3ffbc564, prio:22, stack:2048 tcpip_task_hdlxxx : 3ffbeca8, prio:20,stack:2048 phy_version: 80, Aug 26 2016, 13:04:06, 0 pp_task_hdl : 3ffc34f0, prio:23, stack:8192 :>enter uart init uart init wait fifo succeed exit uart init IDF version : master(db93bceb) WIFI LIB version : master(934d079b) ssc version : master(r283 4d376412) !!!ready!!! mode : softAP(32:ae:a4:cc:4d:18) dhcp server start:(ip: 192.168.4.1, mask: 255.255.255.0, gw: 192.168.4.1) +WIFI:AP_START
SPIRAM対応版ESP32用MicroPythonを入手
MicroPython - Python for microcontrollers
esp32spiram-20190529-v1.11.bin
ファームの焼き方(一般化ルール)
esptool.py --port <usb_port> erase_flash esptool.py --chip esp32 --port <usb_port> write_flash -z 0x1000 <firm>
cygwinから焼く場合
esptool.py --port /dev/ttyS11 erase_flash esptool.py --chip esp32 --port /dev/ttyS11 write_flash -z 0x1000 esp32spiram-20190529-v1.11.bin
焼く前に、ツールが正しく動ているか、無難なコマンドでちょっと確認。以下はchip_id取得コマンドの例
$ esptool.py --port /dev/ttyS11 chip_id esptool.py v2.6 Serial port /dev/ttyS11 Connecting..... Detecting chip type... ESP32 Chip is ESP32D0WDQ5 (revision 1) Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, BLK3 partially reserved, Coding Scheme 3/4 MAC: 30:ae:a4:cc:4d:18 Uploading stub... Running stub... Stub running... Warning: ESP32 has no Chip ID. Reading MAC instead. MAC: 30:ae:a4:cc:4d:18 Hard resetting via RTS pin...
大丈夫なようなので、、フラッシュ消去>ファーム書き込みをやってみる。
flash消去
$ esptool.py --port /dev/ttyS11 erase_flash esptool.py v2.6 Serial port /dev/ttyS11 Connecting....... Detecting chip type... ESP32 Chip is ESP32D0WDQ5 (revision 1) Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, BLK3 partially reserved, Coding Scheme 3/4 MAC: 30:ae:a4:cc:4d:18 Uploading stub... Running stub... Stub running... Erasing flash (this may take a while)... Chip erase completed successfully in 9.2s Hard resetting via RTS pin...
ファームを焼いた
$ esptool.py --chip esp32 --port /dev/ttyS11 write_flash -z 0x1000 firm/esp32spiram-20190529-v1.11.bin esptool.py v2.6 Serial port /dev/ttyS11 Connecting.... Chip is ESP32D0WDQ5 (revision 1) Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, BLK3 partially reserved, Coding Scheme 3/4 MAC: 30:ae:a4:cc:4d:18 Uploading stub... Running stub... Stub running... Configuring flash size... Auto-detected Flash size: 4MB Compressed 1221600 bytes to 743973... Wrote 1221600 bytes (743973 compressed) at 0x00001000 in 66.1 seconds (effective 147.9 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...
ボードをリセットしてブートメッセージを確認、SPI RAM 40mとなっている。こ、、これは、40MBか!!(追記:そんなことはない)
$ cat /dev/ttyS11 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:4928 ho 0 tail 12 room 4 load:0x40078000,len:10188 load:0x40080400,len:6736 entry 0x400806e8 I (500) spiram: Found 64MBit SPI RAM device I (500) spiram: SPI RAM mode: flash 40m sram 40m I (500) spiram: PSRAM initialized, cache is in low/high (2-core) mode. I (506) cpu_start: Pro cpu up. I (510) cpu_start: Application information: I (515) cpu_start: Compile time: 07:47:57 I (520) cpu_start: Compile date: May 29 2019 I (525) cpu_start: ESP-IDF: v3.3-beta1-268-g5c88c5996 I (532) cpu_start: Starting app cpu, entry point is 0x40082e48 I (0) cpu_start: App cpu up. I (1397) spiram: SPI SRAM memory test OK I (1398) heap_init: Initializing. RAM available for dynamic allocation: I (1398) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM I (1404) heap_init: At 3FFB9DD0 len 00026230 (152 KiB): DRAM I (1411) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (1417) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (1424) heap_init: At 40097B1C len 000084E4 (33 KiB): IRAM I (1430) cpu_start: Pro cpu start user code I (106) cpu_start: Starting scheduler on PRO CPU. I (0) cpu_start: Starting scheduler on APP CPU. MicroPython v1.11 on 2019-05-29; ESP32 module with ESP32 Type "help()" for more information. >>>
replから再確認
>>> gc.mem_free() 4093248 >>> gc.collect() >>> gc.mem_free() 4093344
409K?? 40MのRAMはどこに割り当てられているのやら。。
(追記:あまりに気が焦って桁を間違っている。
(/ 4093344.0 1024 1024) // lisp S式 (Emacs使ってるので)
3.903717041015625
3.9MBで、約4MB使える状態で立ち上がっている。)
起動した直後のヒープの状態
>>> micropython.mem_info(1) stack: 752 out of 15360 GC: total: 4098240, used: 5776, free: 4092464 No. of 1-blocks: 45, 2-blocks: 13, max blk sz: 264, max free sz: 255770 GC memory layout; from 3f817740: 00000: h=hhhhMh=DBhhDBBBBhhh===h===hhh==h============================== 00400: ================================================================ 00800: ================================================================ 00c00: ================================================================ 01000: =========================================Bhhh=BDhhLhhhBh===h=h=B 01400: ShTh=h=h===hhh=h=BSh===hThh=h=BhBhh==...h=......h=.............. (3996 lines all free) e8800: ............
マークの意味は以下
. フリーブロック h ヘッドブロック = テイルブロック m マーク付きヘッドブロック T タプル L リスト D 辞書 F 浮動小数点 B バイトコード M モジュール
引用元:
https://micropython-docs-ja.readthedocs.io/ja/latest/reference/constrained.html#reporting
ESP32のFlashファイルシステムにファイルを転送する。ampyを使ってみる。
GitHub - pycampers/ampy: Adafruit MicroPython Tool - Utility to interact with a MicroPython board over a serial connection.
これまではIDEでファイル転送を行っていたけど大がかりなので、コマンドラインでさくっと使えるampyでファイル転送等を行う予定。テスト操作
pip3 install adafruit-ampy $ ampy -p /dev/ttyS11 get boot.py # This file is executed on every boot (including wake-boot from deepsleep) #import esp #esp.osdebug(None) #import webrepl #webrepl.start()
■ご参考
cygwinでシリアルポートのデバイス名の判断方法
cygwinで/devと打ち込むとデバイス一覧が出て、ttyS11だろうとあたりを付ける。合っているか確認のため、cat /dev/ttyS11としてボードをリセット、起動メッセージがずらずら出たのこれでよし
$ ls /dev clipboard dsp null scd0 sda3 sdb3 stdin urandom conin fd ptmx sda sdb shm stdout windows conout full pty0 sda1 sdb1 sr0 tty zero console mqueue random sda2 sdb2 stderr ttyS11 cat /dev/ttyS11
https://micropython-docs-ja.readthedocs.io/ja/latest/index.html