ESP8266 更新韌體使用Arduino當USB to Serial

使用Arduino更新ESP8266 firmware

Arduino 變成 USB to Serial文章已知如何將Arduino變成USB to Serial的功能,接下來利用這個方法配合Arudino程式讓ESP8266能進入UART0啟動的韌體更新模式再透過ESPTool更新韌體。

連接電路:

透過圖上提供的線路,將你的ESP8266與Arduino連接:

ESP8266 Arduino 說明
Vcc 3.3V 電源
GND GND 接地
TX RX 互接
RX TX 互接
GPIO0 2 IO埠
CH_PD 3 晶片選擇
RST 4 重置

撰寫ESP8266程式碼

要讓ESP8266進入UART0啟動的更新模式至少要將GPIO0低電位GPIO2高電位,但因GPIO2在ESP8266上電後預設為高電位,不另外接到高電位,只透過程式將連接GPIO0的PIN2輸出LOW,CH_PD連接PIN3輸出HIGH,並且將RST接入Arduino中增加一個重置ESP8266的功能

//-----------start-----------
     int ch_pd = 3;
     int gpio0 = 2;
     int rst = 4;

     void setup() {
       pinMode(ch_pd, OUTPUT);
       pinMode(gpio0, OUTPUT);
       pinMode(rst, OUTPUT);
       digitalWrite(ch_pd, HIGH);
       digitalWrite(gpio0,LOW);
       //RESET ESP8266
       digitalWrite(rst,HIGH);
       delay(50);
       digitalWrite(rst,LOW);
       delay(200);
       digitalWrite(rst,HIGH);
     }

     void loop()
     {
     }
//------------end------------

程式寫好後將程式下載至Arudino版子,並且更新時需讓Arduino板子重新接上USB線才會讓ESP8266進入更新模式

更新ESP8266 韌體(FW)

Linux or OS X

更新韌體的主程式名為ESPTool,由Fredrik Ahlberg開發,目前已經由樂鑫官方負責維護,丹尼使用ESPTool 1.3才能符合下面操作範例(2.0版已加入ESP32),因是python寫成的,在使用時確定你的環境已經有python,新版1.3已支援python 2.7與python 3,確定你是python哪版本:

    python --version

丹尼目前的環境為:

    Python 3.6.0

自行加入pySerial對應版本的Library,以Arich Linux為例:

    pacman -Ss pyserial


    community/python-pyserial 3.2.1-2
        Multiplatform Serial Port Module for Python
    community/python2-pyserial 3.2.1-2
        Multiplatform Serial Port Module for Python

    sudo pacman -S community/python-pyserial

安裝完成後,執行esptool.py,無錯誤產生的話會看到help說明:


esptool.py v1.3 - ESP8266 ROM Bootloader Utility positional arguments: {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash,verify_flash,erase_flash,version} Run esptool {command} -h for additional help load_ram 將映像檔載入RAM中並行執行 dump_mem 轉存記憶體資料至檔案(轉存ESP資料) read_mem 讀取記憶體指定位址並存至檔案 write_mem 讀取檔案內容並寫入至記憶體指定位址 write_flash 將檔案內容寫入至SPI Flash run 執行Flash裡的應用程式碼 image_info 轉存可執行應用映像檔的標頭 make_image 從二進位檔建立可執行的應用 elf2image 從ELF檔建立可執行的應用 read_mac 從OTP ROM讀取MAC位址 chip_id 從OTP ROM讀取晶片資訊 flash_id 讀取Flash出廠資訊(可透過此ID得知容量大小) read_flash 取讀SPI Flash內容 verify_flash 驗證bin與Flash erase_flash 抹除SPI Flash version 列印出esptool版本 optional arguments: -h, --help show this help message and exit --port PORT, -p PORT Serial埠名稱(Linux ttyxxx,macOS cu.xxx,Windows COMx) --baud BAUD, -b BAUD Serial埠速度

韌體上傳命令示範:


./esptool.py -p /dev/ttyUSB0 write_flash 0x00000 v0.9.5.2\ AT\ Firmware.bin

其中-p後所接的是你的通訊埠名稱(macOS以cu.命名規則,Linux以ttyXXX,Windows以COMx),韌體寫入位址從0x00000開始,來源檔為0x00000 v0.9.5.2 AT Firmware.bin,一切順利後就會更新完成:


./esptool.py -p /dev/cu.usbmodem5d11 write_flash 0x00000 v0.9.5.2\ AT\ Firmware.bin Connecting... Erasing flash... Writing at 0x0007ef00... (100 %)

Windows

Windows上有NodeMcu團隊開發的工具容易使用,根據你的環境下載版本

  1. 32bit

  2. 64bit

選擇Arduino使用的通訊埠號:

Config頁面,每個韌體更新方式不同,依照安信可提供的韌體大小是符合整個flash大小,不需要分段更新,所以只要設定寫入從0x00000,並且選擇好對應的檔案,並將選擇它(選擇後會顯示x):

基本上這些內容只需要注意Flash size,因為ESP8266設計上是以外接SPI Flash來運作,模組一開始主要都是使用256kBytes,後來官方新增功能愈來愈多就發展到512kByte,現在幾乎都是1MBytes以上,請根據你模組上面的SPI Flash編號來判斷,通常都是25xx開頭,但Flash以bit來定義,所以會變成:

編號 Flash PC計算單位
W25Q20 2Mbits 256kBytes
GD25Q16B 2Mbits 256kBytes
W25Q40 4Mbits 512kBytes
W25Q80 8Mbits 1024kBytes
W25Q16 16Mbits 2048KBytes
W25Q32 32Mbits 4096kBytes
BG25Q32 32Mbits 4096kBytes
GD25Q32B 32Mbits 4096kBytes

1024 bits = 1k

丹尼很久以前購買的ESP-01是512kBytes的版本,在此說明一下,官方版本的韌體從SDK V1.5.0以後採用1024kBytes的容量(因新增許多AT命令造成容量過大),所以購買模組時請跟賣家確認是否超過1024kBytes的版本。一切都設定好再切至Operation的頁面按下Flash進行更新,更新過程記錄切至Log頁就能看到。

補充

目前ESP8266發展愈來愈成熟,韌體主流為1MBytes(8Mbits),安信可也提供符合新版SDK的自訂韌體供選擇,前往ESP8266 最新SDK发布查看安信可最新的自訂韌體,現在新版的韌體也建議使用樂鑫提供的ESP_DOWNLOAD_TOOL,安信可也提供燒錄說明如何为 ESP 系列模组烧录固件

燒錄前的檢查確認避免燒錄失敗:

電壓、電流

ESP8266所使用的為3.3V電壓、電流至少大於300mA,這些來源都必需穩定,未確認USB to Serial提供的3.3V是否穩定時請勿使用,不穩定會造成燒錄到一半失敗或是無法切至燒錄模式,詳細說明請參考ESP8266 電源電路研究

確認flash size,選擇對應的韌體大小

讀取flash id

    esptool.py -p /dev/ttyUSB0 -b 230400 flash_id


得到flash相關資訊:


esptool.py v1.3 Connecting.... Manufacturer: ef Device: 4016

取得flash_id資料後重新組合為1640EF(DeviceL + DeviceH + Manufacturer),再經由Esp.cpp擷取出來的程式內容自行比對並取得內容:

uint32_t EspClass::getFlashChipSizeByChipId(void) {
    uint32_t chipId = getFlashChipId();
    /**
     * Chip ID
     * 00 - always 00 (Chip ID use only 3 byte)
     * 17 - ? looks like 2^xx is size in Byte ?     //todo: find docu to this
     * 40 - ? may be Speed ?                        //todo: find docu to this
     * C8 - manufacturer ID
     */
    switch(chipId) {

        // GigaDevice
        case 0x1740C8: // GD25Q64B
            return (8_MB);
        case 0x1640C8: // GD25Q32B
            return (4_MB);
        case 0x1540C8: // GD25Q16B
            return (2_MB);
        case 0x1440C8: // GD25Q80
            return (1_MB);
        case 0x1340C8: // GD25Q40
            return (512_kB);
        case 0x1240C8: // GD25Q20
            return (256_kB);
        case 0x1140C8: // GD25Q10
            return (128_kB);
        case 0x1040C8: // GD25Q12
            return (64_kB);

        // Winbond
        case 0x1640EF: // W25Q32
            return (4_MB);
        case 0x1540EF: // W25Q16
            return (2_MB);
        case 0x1440EF: // W25Q80
            return (1_MB);
        case 0x1340EF: // W25Q40
            return (512_kB);

        // BergMicro
        case 0x1640E0: // BG25Q32
            return (4_MB);
        case 0x1540E0: // BG25Q16
            return (2_MB);
        case 0x1440E0: // BG25Q80
            return (1_MB);
        case 0x1340E0: // BG25Q40
            return (512_kB);

        default:
            return 0;
    }
}

1640EF為例得到的資料為:

        // Winbond
        case 0x1640EF: // W25Q32
            return (4_MB);

Winbond W25Q32 flash型號並且容量為4MBytes(32Mbits)。

確認韌體的結構

使用官方提供的分段燒錄韌體(參考ESP8266 韌體)要確定每段都有燒錄正確,官方提供的SDK目錄結構來說,AT command 韌體更新說明都會放在bin/at/README.txt

***********************BOOT MODE***********************
download:
Flash size 8Mbit: 512KB+512KB
boot_v1.2+.bin          0x00000
user1.1024.new.2.bin    0x01000
esp_init_data_default.bin   0xfc000 (optional)
blank.bin               0x7e000 & 0xfe000

Flash size 16Mbit: 512KB+512KB
boot_v1.2+.bin          0x00000
user1.1024.new.2.bin    0x01000
esp_init_data_default.bin   0x1fc000 (optional)
blank.bin               0x7e000 & 0x1fe000

Flash size 16Mbit-C1: 1024KB+1024KB
boot_v1.2+.bin          0x00000
user1.2048.new.5.bin    0x01000
esp_init_data_default.bin   0x1fc000 (optional)
blank.bin               0xfe000 & 0x1fe000

Flash size 32Mbit: 512KB+512KB
boot_v1.2+.bin          0x00000
user1.1024.new.2.bin    0x01000
esp_init_data_default.bin   0x3fc000 (optional)
blank.bin               0x7e000 & 0x3fe000

Flash size 32Mbit-C1: 1024KB+1024KB
boot_v1.2+.bin          0x00000
user1.2048.new.5.bin    0x01000
esp_init_data_default.bin   0x3fc000 (optional)
blank.bin               0xfe000 & 0x3fe000

***********************NON-BOOT MODE***********************
download
eagle.flash.bin     0x00000
eagle.irom0text.bin 0x40000
blank.bin
    Flash size 4Mbit:   0x3e000 & 0x7e000
    Flash size 8Mbit:   0x7e000 & 0xfe000
    Flash size 16Mbit:      0x7e000 & 0x1fe000
    Flash size 16Mbit-C1:   0xfe000 & 0x1fe000
    Flash size 32Mbit:      0x7e000 & 0x3fe000
    Flash size 32Mbit-C1:   0xfe000 & 0x3fe000
esp_init_data_default.bin    (optional)
    Flash size 4Mbit:   0x7c000
      Flash size 8Mbit:   0xfc000
    Flash size 16Mbit:      0x1fc000
    Flash size 16Mbit-C1:   0x1fc000
    Flash size 32Mbit:      0x3fc000
    Flash size 32Mbit-C1:   0x3fc000

*NOTICE*:
UPDATE is not supported in non-boot mode

***********************************************************

Update steps
1.Make sure TE(terminal equipment) is in sta or sta+ap mode
ex. AT+CWMODE=3
    OK

    AT+RST

2.Make sure TE got ip address
ex. AT+CWJAP="ssid","12345678"
    OK

    AT+CIFSR
    192.168.1.134

3.Let's update
ex. AT+CIUPDATE
    +CIPUPDATE:1    found server
    +CIPUPDATE:2    connect server
    +CIPUPDATE:3    got edition
    +CIPUPDATE:4    start start

    OK

note. If there are mistakes in the updating, then break update and print ERROR.

第三方韌體請確認韌體是否整合好還是屬於分段燒錄,以安信可提供的則是已經整合好的,從位址0x00000開始燒錄就能完成。

清除flash

必要時,自行清楚所有flash內容,避免有一些未知的內容被引用:

    esptool.py -p /dev/ttyUSB0 -b 230400 erase_flash


512kBytes 韌體

如果你是買512kBytes版本,丹尼提供使用官方SDK V1.3的版本整合成適合512kBytes版本使用的單一更新韌體檔案ESP8266_V1.3_FOR_512k,可以使用任何的ESP8266更新程式來更新韌體。

參考資料

ESP8266 Firmware Update with Arduino Board

安信可v0.9.5.2AT固件支持SmartLink,带0.9.5.2APK,支持OTA!

ESPTool

nodemcu-flasher

丹尼 ESP8266

V1.3 for 512k

更新日誌

日期 修訂內容
2017/05/24 修正文字內容
2017/03/21 更新內容並增加補充項目
2016/03/28 更新接腳、新增Windows更新工具

  • 葉倚嘉

    我試了這個方法,我發現一些奇怪的地方,我是TX接TX、RX接RX,才可以用 跟你寫得不太一樣? 而且ESP8266只能接3.3V,如果照你這樣接,還可能會燒壞板子…

    • Arduino線路上有提供3.3V,一般使用還能勉強供ESP8266使用,至於ESP8266的RX能接收3.3V、5V的輸入,基本上不會有問題,而它的TX出來最高3.3V對於Arduino的Hi,Low準位判斷也不會有問題,可以參考參考

  • L LW

    不好意思小弟不太懂這裡的敘述 “程式下載完成後再另外準備firmware,這裡使用的是物聯世界討論區提供的,下載後請與ESPTool放在同一個位置,並且輸入:” 輸入部分適用CMD輸入?還是python? 謝謝您

  • L LW

    不好意思小弟想請教下這裡的敘述

    “程式下載完成後再另外準備firmware,這裡使用的是物聯世界討論區提供的,下載後請與ESPTool放在同一個位置,並且輸入:./esptool.py -p /dev/cu.usbmodem5d11 write_flash 0x00000 v0.9.5.2 AT Firmware.bin “

    是只適用於OS X的吧?

    謝謝您

    • 範例以OSX為主,你使用Linux、Windows必需要變更一下Serial名稱,例如: ./esptool.py -p /dev/ttyS0 write_flash 0x00000 v0.9.5.2 AT Firmware.bin

      • L LW

        好的謝謝您!!! 不過”./esptool.py -p /dev/ttyS0 write_flash 0x00000 v0.9.5.2 AT Firmware.bin”是Windows的指令嗎? 不好意思打擾了

        • 沒有喔!windows需要安裝windows版的python https://www.python.org/downloads/windows/

          • L LW

            小弟那些都處理好了包括pySerial的部分 目前只差燒錄 只是不知道Windows該下甚麼指令做燒錄QAQ 不好意思QAQ

          • python esptool.py -p COM1 write_flash 0x00000 v0.9.5.2 AT Firmware.bin

          • L LW

            不好意思能再請教一下嗎

            usage: esptool write_flash [-h] [–flash_freq {40m,26m,20m,80m}]

                                   [--flash_mode {qio,qout,dio,dout}]
            
                                   [--flash_size {4m,2m,8m,16m,32m,16m-c1,32m-c1,32m-c2}`
            

            ]

                                   [--verify]
            
                                   <address> <filename> [<address> <filename> ...]`
            

            esptool write_flash: error: argument

            <

            address> : [Errno 2] No such fil

            e or directory: ‘v0.9.5.2\’

            是基於甚麼原因產深的ERROR呢?謝謝您!!!

          • 路徑參數錯了。你確認一下Firmware.bin路徑,把”v0.9.5.2 AT Firmware.bin”換成正確的

          • L LW

            C:UsersAdminDesktopesptool-master>python esptool.py -p COM3 write_flash 0x00

            000 Firmware.bin

            Connecting…

            A fatal error occurred: Failed to connect to ESP8266

            是開始跑了,不過這ERROR說無法連結到(我的是COM3沒錯)QAQ

          • 試試將COM3改成\.COM3

          • 如果您是配合上面arduino使用的話,重新啟動arduino試試

          • L LW

            好的,等等試試,謝謝您

          • L LW

            還是不行QAQ 而且小弟的TX、RX反過來才會開始燒(藍色LED閃爍),當然還是無法燒錄,會失敗QAQ

          • 你的失敗訊息是什麼啊?

          • L LW

            依樣是 A fatal error occurred: Failed to connect to ESP8266 不好意思 小弟在想看看好了