使用python同时烧录多个esp8266并在烧录完成后重启
同事在使用官方的EspFlashDownloadTool的时候,虽然能一次同时烧录8个,然而烧录完毕后该工具不会自动重启ESP固件,每次还需要为每个设备手动去选择串口,以及为不同产品选择不同的bin文件。
为什么用Python开发:本来对node.js比较熟悉,然而考虑到要给同事安装,装完node又装python 显得很麻烦,而且node的serialport模块需要安装node-gyp,node-gyp需要vs studio本地编译,并且项目依赖还需要npm install。最坑爹的是serialport没有promise化,自动化和串口交互就会掉入回调地狱(虽然本项目不涉及)。而python的所有模块统一装在一起,pyserial也不需要二次编译,而且似乎pyserial也比serialport的功能强大一些,就还是选择python开发,虽然一两年每碰python手生得很了——得抱着本书在旁边当字典。
最终源码只需要单个文件,如起个名字叫autoflash.py,关联python可以直接运行。
安装过程:
1. 装python2.7.14,装的时候添加python路径的选项要勾上;
2. 更换pip源为豆瓣,(国内开发python靠豆瓣,开发node靠淘宝啊),在用户目录(如C:\users\xxx)下新建pip\pip.ini ,输入:
[global]
index-url = https://pypi.douban.com/simple
- 安装esptool
pip install esptool
- 将autoflash.py复制到固件目录下。
- 修改一下源码,里面固件文件名、烧录地址、esptool.py的名称有不对的地方,改成跟自己的环境相同的。
这个是很奇怪的,我使用pip install esptool安装后的文件叫esptool.exe,而同事电脑(都是 win10 x64)装好却是esptool.py(与官方介绍的相同)。
另外,我的不需要shell=True也可以调用subprocess,而他的电脑却需要,否则会报错:windowserror error 2。Error 2查了一下,是找不到文件的意思,连dir都找不到。加上shell=True就好了。
解释一下subprocess,Popen默认是开新的子进程的。等待进程结束使用wait或者communicate,不过建议用communicate,因为后者机制上更好一些,不容易出问题。
serial_port方法的源码来自于Seg
源码如下:
#!/usr/bin/env python
from __future__ import division, print_function
import sys
import glob
import subprocess
import multiprocessing as mp
import shlex
import serial
def serial_ports():
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
return result
def main():
sps = serial_ports()
print(sps)
processes = {}
for sp in sps:
cmd = shlex.split('esptool.py --port ' + sp +
' --baud 1152000 --after hard_reset write_flash 0x00000 \
eagle.flash.bin 0x10000 eagle.irom0text.bin 0x3fc000 esp_init_data_default.bin')
print(cmd)
processes[sp] = subprocess.Popen(cmd)
for sp in sps:
processes[sp].communicate()
print('[Finished]')
if __name__ == '__main__':
main()
评论已关闭