使用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团队开发的工具容易使用,根据你的环境下载版本
选择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!
更新日志
日期 | 修订内容 |
---|---|
2017/05/24 | 修正文字内容 |
2017/03/21 | 更新内容并增加补充项目 |
2016/03/28 | 更新接脚、新增Windows更新工具 |