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更新工具