同事在使用官方的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
  1. 安装esptool
pip install esptool
  1. 将autoflash.py复制到固件目录下。
  2. 修改一下源码,里面固件文件名、烧录地址、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()

标签: none 阅读量: 1180

评论已关闭