2018年9月16日 星期日

bpi:bit ESP32 開發板測試 (一) : 燒錄 MicroPython 韌體

昨晚飯後開始測試前天 Tim 兄給我的 rpi: bit 板子, 原想先試試原裝之 Webduino 韌體, 但 blockly 的網頁介面我一直都沒用過, 得花點時間熟悉, 不如直接燒 MicroPython 較快. 於是我用 ESP8266Flasher.exe 去燒, 發現 Log 一直停在 "Finding ESP8266" 不動, 原來此燒錄程式是 ESP8266 專用, 不能用來燒 ESP32.

在網上查詢 "ESP32 Flashing" 找到下列文章, 原來可用 Python 的 esptool 套件來燒 ESP32 :

ESP8266 教程:使用 esptool.py 烧录 ESP Easy 固件

2019-07-15 補充 :

bpi::bit 最新韌體下載如下 (看最底下補充) :

https://github.com/BPI-STEAM/BPI-BIT-MicroPython/releases

先用 pip3 安裝 esptool 套件 :

C:\Users\user>pip3 install esptool
Collecting esptool
  Downloading https://files.pythonhosted.org/packages/69/ce/2b572f10b11b25c1aa29ed52c161e0117a4d37cca215b81d6356ab3f446e/esptool-2.5.0.tar.gz (75kB)
 Requirement already satisfied: pyserial>=3.0 in c:\python36\lib\site-packages (from esptool) (3.3)
Collecting pyaes (from esptool)
  Downloading https://files.pythonhosted.org/packages/44/66/2c17bae31c906613795711fc78045c285048168919ace2220daa372c7d72/pyaes-1.6.1.tar.gz
Collecting ecdsa (from esptool)
  Downloading https://files.pythonhosted.org/packages/63/f4/73669d51825516ce8c43b816c0a6b64cd6eb71d08b99820c00792cb42222/ecdsa-0.13-py2.py3-none-any.whl (86kB)
Building wheels for collected packages: esptool, pyaes
  Running setup.py bdist_wheel for esptool ... done
  Stored in directory: C:\Users\user\AppData\Local\pip\Cache\wheels\c8\90\2e\910c1f4e74ea39cfe6f1eb7a71fe03d99e7048ef11d1fd75fc
  Running setup.py bdist_wheel for pyaes ... done
  Stored in directory: C:\Users\user\AppData\Local\pip\Cache\wheels\bd\cf\7b\ced9e8f28c50ed666728e8ab178ffedeb9d06f6a10f85d6432
Successfully built esptool pyaes
Installing collected packages: pyaes, ecdsa, esptool
  The scripts espefuse.exe, espsecure.exe and esptool.exe are installed in 'c:\python36\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed ecdsa-0.13 esptool-2.5.0 pyaes-1.6.1

esptools 會被安裝在 Python 的 Scripts 目錄下, 檢查此目錄可找到多了一個 esptools.exe 檔 (不是 esptools.py), 依照該為所說先用下列指令查詢板子性能配置 :

D:\ESP8266>esptool.exe --port COM4 flash_id 
esptool.py v2.5.0
Serial port COM4
Connecting........___
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core  (支援 WiFi, 藍芽, 雙核心 CPU)
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Manufacturer: c8
Device: 4016 
Detected flash size: 4MB
Hard resetting via RTS pin...

ESP-WROOM-32 Flash Size

接著用下列指令清除 Flash 裡面的舊資料 :

D:\ESP8266>esptool.exe --port COM4 erase_flash
esptool.py v2.5.0
Serial port COM4
Connecting........_
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 0.9s 
Hard resetting via RTS pin...

然後去 MicroPython 下載最新版之 1.9.4 韌體, 以下列指令進行燒錄 :

D:\ESP8266>esptool.exe --port COM4 --baud 115200 write_flash -fm dio -fs 4MB 0x00000 esp8266-20180511-v1.9.4.bin
esptool.py v2.5.0
Serial port COM4
Connecting........_____.
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Compressed 604872 bytes to 394893...
Wrote 604872 bytes (394893 compressed) at 0x00000000 in 35.1 seconds (effective 137.7 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

約花了 30 秒左右從 0% 到 100% 成功燒錄, 但是利用 Putty 連線板子卻出現下列連續不斷的 Reset 訊息, 無法進入 REPL 介面 :

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun  8 2016 00:22:57

與 Tim 兄聯繫報告燒錄結果, 他建議我使用 Github 上他所提供的燒錄程式試試看 :

https://github.com/BPI-STEAM/BPI-BIT-MicroPython/releases/tag/FlashTool
# https://github.com/BPI-STEAM/BPI-BIT-MicroPython

在 HowToFlash 頁面下載 AutoErase.py 與 AutoFlash.py 兩個程式, 以及 Firmware.bin 韌體, 先執行 AutoErase.py 洗掉 FLASH 裡面的舊資料, 然後再執行 AutoFlash.py 燒錄 :

D:\ESP8266>python AutoErase.py
Looking for upload port...
Auto-detected:COM4
esptool.py v2.5.0
Serial port COM4
Connecting....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Erasing flash (this may take a while)...
Chip erase completed successfully in 2.7s
Hard resetting via RTS pin...
請按任意鍵繼續 . . .

D:\ESP8266>python AutoFlash.py
Looking for upload port...
Auto-detected:COM4
esptool.py v2.5.0
Serial port COM4
Connecting........_____.
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Compressed 41484 bytes to 11055...
Wrote 41484 bytes (11055 compressed) at 0x00001000 in 0.1 seconds (effective 2358.6 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
請按任意鍵繼續 . . .

注意, AutoFlash.py 會自動去找目前目錄下的 Firmware.bin 來燒錄, 不須指定, 因此如果去 MicroPython 官網下載韌體來燒錄, 必須先將其更名為 Firmware.bin 才行. 看起來燒錄都正常, 但用 Putty 連線還是出現一樣的 Reset 訊息 :

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun  8 2016 00:22:57

仔細看訊息, 其中的 flash read error 似乎是因為讀取 Flash 錯誤造成重起始嗎?

補充 :

仔細檢視上面的紀錄發現搞了大烏龍, 以上用 esptools 燒錄的 MicroPython 韌體竟然是 ESP8266 的 (下載錯了), 應該是這個 esp32 的才對 :

http://micropython.org/download/#esp32




重新燒錄 :

D:\ESP8266>esptool.exe --port COM4 erase_flash
esptool.py v2.5.0
Serial port COM4
Connecting........_
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 2.2s
Hard resetting via RTS pin...

D:\ESP8266>esptool.exe --port COM4 --baud 115200 write_flash -fm dio -fs 4MB 0x00000 esp32-20180916-v1.9.4-541-g7e3dd9f8a.bin  (參數不正確, 參考底下補充)
esptool.py v2.5.0
Serial port COM4
Connecting......
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Compressed 1053200 bytes to 662898...
Wrote 1053200 bytes (662898 compressed) at 0x00000000 in 59.0 seconds (effective 142.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

可結果還是一樣. 但是若改用 AutoFlash.py 來燒的話就成功了, 我猜想應該是 esptool.exe 後面帶的參數不正確的關係. 用 Putty 連線可見 Reset 後就進入 REPL 介面了 :

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:4732
load:0x40078000,len:7496
load:0x40080400,len:5512
entry 0x4008114c
I (389) cpu_start: Pro cpu up.
I (389) cpu_start: Single core mode
I (389) heap_init: Initializing. RAM available for dynamic allocation:
I (393) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (399) heap_init: At 3FFC4F48 len 0001B0B8 (108 KiB): DRAM
I (405) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (411) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (418) heap_init: At 40091448 len 0000EBB8 (58 KiB): IRAM
I (424) cpu_start: Pro cpu start user code
I (218) cpu_start: Starting scheduler on PRO CPU.
OSError: [Errno 2] ENOENT
MicroPython v1.9.4-541-g7e3dd9f8a on 2018-09-16; ESP32 module with ESP32
Type "help()" for more information.
>>>
>>> help()
Welcome to MicroPython on the ESP32!

For generic online docs please visit http://docs.micropython.org/

For access to the hardware use the 'machine' module:

import machine
pin12 = machine.Pin(12, machine.Pin.OUT)
pin12.value(1)
pin13 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP)
print(pin13.value())
i2c = machine.I2C(scl=machine.Pin(21), sda=machine.Pin(22))
i2c.scan()
i2c.writeto(addr, b'1234')
i2c.readfrom(addr, 4)

Basic WiFi configuration:

import network
sta_if = network.WLAN(network.STA_IF); sta_if.active(True)
sta_if.scan()                             # Scan for available access points
sta_if.connect("<AP_name>", "<password>") # Connect to an AP
sta_if.isconnected()                      # Check for successful connection

Control commands:
  CTRL-A        -- on a blank line, enter raw REPL mode
  CTRL-B        -- on a blank line, enter normal REPL mode
  CTRL-C        -- interrupt a running program
  CTRL-D        -- on a blank line, do a soft reset of the board
  CTRL-E        -- on a blank line, enter paste mode

For further help on a specific object, type help(obj)
For a list of available modules, type help('modules')
>>>

再補充 :

我發現 MicroPython 官網下載頁 ESP32 韌體有分 standard 與 with SPIRAM 兩種, 我又下載 with SPIRAM 版用 AutoFlash 燒錄, 結果不行. 與 Tim 兄討論請教, 原來此板使用 wroom 模組無 SPIRAM, 要 wrover 模組才有.

OK, 總結以上燒錄過程, 要順利燒錄韌體應使用 GitHub 下載之 AutoFlash.py, 要下載 ESP32 的韌體, 不要下到 ESP8266 的.

韌體燒錄成功後便可測試一下板子硬體狀態, 但 v.1.9.4 版韌體好像移除了 port_diag 模組, 而且 esp 模組也沒有 check_fw() 函數了  :

MicroPython v1.9.4-541-g7e3dd9f8a on 2018-09-16; ESP32 module with ESP32
Type "help()" for more information.
>>> import port_diag 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named 'port_diag'
>>> import esp 
>>> esp.check_fw()   
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'check_fw'

其次是匯入 webrepl_setup 模組開啟 REPL 功能並設定密碼 : 

>>> import webrepl_setup
WebREPL daemon auto-start status: disabled

Would you like to (E)nable or (D)isable it running on boot?
(Empty line to quit)
> E
To enable WebREPL, you must set password for it
New password (4-9 chars): 123456
Confirm password: 123456
Changes will be activated after reboot
Would you like to reboot now? (y/n) y
New password (4-9 chars): 123456
Confirm password: 123456


No further action required

接下來測試檔案目錄, 參考 ESP8266 文章 :

MicroPython on ESP8266 (六) : 檔案系統測試

>>> import os 
>>> os.uname() 
(sysname='esp32', nodename='esp32', release='1.9.4', version='v1.9.4-541-g7e3dd9f8a on 2018-09-16', machine='ESP32 module with ESP32')
>>> os.listdir() 
['boot.py', 'webrepl_cfg.py']

其中 webrepl_cfg.py 是上面開啟 web repl 後新增之檔案.

Get on the Good Foot with MicroPython on the ESP32, Part 1 of 2
https://hackmd.io/s/Hyn2jRIP7


2019-07-12 補充 :

這兩天有空又找出 rpi:bit 來玩, 找到下面網頁有相關資訊 :

# bpi:bit 玩 python => micro python
https://bpi-steam-docs.readthedocs.io/zh_CN/latest/bpi-mpy/tutorials/index.html

上面懷疑 esptool 參數錯誤, 今天下載了最新版 bpi:bit 的 Micropython 韌體, bpi::bit 最新 MicroPython 韌體下載網頁在此 :

https://github.com/BPI-STEAM/BPI-BIT-MicroPython/releases

以下列參數重新燒錄就沒問題了, 上面的參數確實有問題 :

D:\ESP32>esptool.py --port COM4 flash_id 
esptool.py v2.6
Serial port COM4
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, Coding Scheme None
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Manufacturer: c8
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...

D:\ESP32>esptool.py --chip esp32 --port COM4 erase_flash   
esptool.py v2.6
Serial port COM4
Connecting....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, Coding Scheme None
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 5.1s
Hard resetting via RTS pin...

D:\ESP32>esptool.py --chip esp32 --port COM4 write_flash -z 0x1000 firmware-20190623.bin
esptool.py v2.6
Serial port COM4
Connecting......
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, Coding Scheme None
MAC: 30:ae:a4:8f:c6:4c
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 1749248 bytes to 1089447...
Wrote 1749248 bytes (1089447 compressed) at 0x00001000 in 96.4 seconds (effective 145.1 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

重開機 PuTTY 連線結果如下 :

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:4880
ho 0 tail 12 room 4
load:0x40078000,len:9404
load:0x40080400,len:6228
entry 0x400806ec
I (652) cpu_start: Pro cpu up.
I (652) cpu_start: Application information:
I (652) cpu_start: Compile time:     Jun 22 2019 23:54:14
I (655) cpu_start: ELF file SHA256:  0000000000000000...
I (661) cpu_start: ESP-IDF:          v3.3-beta1-694-g6b3da6b18
I (668) cpu_start: Starting app cpu, entry point is 0x40082de8
I (0) cpu_start: App cpu up.
I (678) heap_init: Initializing. RAM available for dynamic allocation:
I (685) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (691) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (697) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (703) heap_init: At 3FFBDB5C len 00000004 (0 KiB): DRAM
I (709) heap_init: At 3FFCFDD0 len 00010230 (64 KiB): DRAM
I (716) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (722) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (728) heap_init: At 40098C08 len 000073F8 (28 KiB): IRAM
I (734) cpu_start: Pro cpu start user code
I (82) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (288) phy: phy_version: 4100, 2a5dd04, Jan 23 2019, 21:00:07, 0, 0
Press "A" to enter the smartconfig mode while the led is rolling
Started wifi in normal mode
MicroPython v1.10-223-g43faa7e85-dirty on 2019-06-23; ESP32 module with ESP32
Type "help()" for more information.
>>>

可見這韌體是在 MicroPython v1.10 版上加料優化後重新編譯的.

用 ampy 檢視檔案系統 :

D:\ESP32>ampy --port com9 get boot.py 
# This file is executed on every boot (including wake-boot from deepsleep)
import esp
esp.osdebug(None)
#import webrepl
#webrepl.start()
import wifi
wifi.ready()

可見系統預載 esp 與 wifi 模組, 且 esp 預設關閉偵測顯示功能, 且未開啟 webrepl 功能.

用 dir() 查詢記憶體物件 :

>>> dir() 
['uos', '__name__', 'wifi', 'gc', 'bdev', 'esp']

確實已匯入 esp 與 wifi, 檢視 esp 物件 :

>>> dir(esp) 
['__class__', '__name__', 'LOG_DEBUG', 'LOG_ERROR', 'LOG_INFO', 'LOG_NONE', 'LOG_VERBOSE', 'LOG_WARNING', 'dht_readinto', 'flash_erase', 'flash_read', 'flash_size', 'flash_user_start', 'flash_write', 'gpio_matrix_in', 'gpio_matrix_out', 'neopixel_write', 'osdebug']
>>> esp.flash_size() 
4194304

因 boot.py 預設關閉了偵測顯示功能, 如果要開啟就呼叫 esp.osdebug(True).

檢查 wifi 物件 :

>>> dir(wifi)     
['__class__', '__name__', 'close', 'disconnect', 'ifconfig', 'isconnected', 'network', 'smartconfig', 'wlan', 'try_connect', 'is_smartconfig', '__irq_sc', 'ready']
>>> dir(wifi.wlan)
['__class__', 'active', 'config', 'connect', 'disconnect', 'ifconfig', 'isconnected', 'scan', 'status']
>>> wifi.wlan.connect('TonyNote8','blablabla')   
>>> wifi.wlan.isconnected()   
True
>>> wifi.wlan.status()
1010
>>> wifi.wlan.ifconfig() 
('192.168.43.68', '255.255.255.0', '192.168.43.1', '192.168.43.1')
>>> wifi.wlan.scan()   
[(b'TonyNote8', b'\x06\xd6\xaa\x04\xfcJ', 11, -60, 3, False), (b'EDIMAX-meinung', b'\x80\x1f\x02G\x1e\xa8', 11, -75, 4, False)]

相關教學文件參考 :

https://docs.micropython.org/en/latest/ (官方文件)

2 則留言 :

溫低哥 提到...

關於ESP32的燒錄參數我也是搞了很久才搞懂,這邊分享一下
希望未來有同樣問題的人可以檢查找錯的時間

安裝Arduino後打開程式
preferences --> show verbose output during upload --> 打勾
上傳任何一個ESP32範例擋到ESP32上
然後你就會看到下面類似的連結 這就是燒錄參數了

C:\Users\logoz\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\2.6.0/esptool.exe --chip esp32 --port COM4 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0xe000 C:\Users\logoz\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1/tools/partitions/boot_app0.bin 0x1000 C:\Users\logoz\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1/tools/sdk/bin/bootloader_dio_80m.bin 0x10000 C:\Users\logoz\AppData\Local\Temp\arduino_build_626737/mqtt_esp32_fine_noconfig_20190225.ino.bin 0x8000 C:\Users\logoz\AppData\Local\Temp\arduino_build_626737/mqtt_esp32_fine_noconfig_20190225.ino.partitions.bin

所以你就得到了各檔案的燒錄位址
0xe000 boot_app0.bin
0x0000 bootloader_dio_80m.bin
0x10000 mqtt_esp32_fine_noconfig_20190225.ino.bin
0x8000 mqtt_esp32_fine_noconfig_20190225.ino.partitions.bin

然後你就可以使用你喜歡的工具或是寫個FlashESP32.bat依照上面參數來燒錄firmware了

小狐狸事務所 提到...

感謝分享!