1. 程式人生 > >python 實現基於XMODEM協議的W600 WiFI晶片韌體燒錄工具

python 實現基於XMODEM協議的W600 WiFI晶片韌體燒錄工具

from optparse import OptionParser
import serial
import xmodem
import os, sys, time
import logging
import pyprind
from binascii import b2a_hex, a2b_hex

"""
Name  : Firmware upgrade tool for winnermicro's W600 device
Note  : use like this: python upload.py -c COM10 -f ./W600_GZ.img
Env   : python v2.7.13
Author: zhangwl
Date  : 20181027
"""

cmd_baudrate_2M = "210A00EF2A3100000080841E00"
baudrate_LS = 115200
baudrate_HS = 2000000
serial_timeout = 0.1

def initialSerialPort(baudrate, port, timeout):   
    s.baudrate = baudrate
    s.port = port
    s.timeout = timeout
    s.open()
    time.sleep(0.1)
    pass

def getc(size, timeout=1):
    return s.read(size)

def putc(data, timeout=1):
    bar.update()
    return s.write(data)

def putc_user(data, timeout=1):
    bar_user.update()
    return s.write(data)

if __name__ == '__main__':

    logging.basicConfig()
    parser = OptionParser(usage="python %prog [options]")
    parser.add_option("-f", dest="bin_path", help="path of bin to be upload")
    parser.add_option("-c", dest="com_port", help="COM port, can be COM1, COM2, ..., COMx")
    (opt, args) = parser.parse_args()


    if not opt.bin_path or not opt.com_port:
        print >> sys.stderr, "\nError: Invalid parameter!! Please specify COM port and bin.\n"
        parser.print_help()
        sys.exit(-1)

    if not os.path.exists(opt.bin_path):
        print >> sys.stderr, "\nError: File [ %s ] not found !!!\n" % (opt.bin_path)
        parser.print_help()
        sys.exit(-1)
        
    s = serial.Serial()
    
    # set W600 into upgrade mode and change its baudrate to 2M bit/s
    initialSerialPort(baudrate_LS, opt.com_port, serial_timeout)
    print >> sys.stderr, "Please reset your W600 device!"
    while True:
        c = s.read(1)
        if c =='C':
            print >> sys.stderr, "second bootloader running low speed!"
            s.write(a2b_hex(cmd_baudrate_2M))
            break
        else:
            s.write(a2b_hex("1B"))
    s.flush()
    s.flushInput()
    s.close()
    time.sleep(0.2)
    
    # check baudrate
    initialSerialPort(baudrate_HS, opt.com_port, serial_timeout)
    while True:
        time.sleep(0.1)
        c = s.read(1)
        if c =='C':
            print >> sys.stderr, "second bootloader running high speed!"
            break
        else:
            s.write(a2b_hex(cmd_baudrate_2M))

    # set progress bar display
    statinfo_bin = os.stat(opt.bin_path)
    bar_user = pyprind.ProgBar(statinfo_bin.st_size/1024+2)
    
    # download firmware in 2M mode
    stream = open(opt.bin_path, 'rb')
    m = xmodem.XMODEM(getc, putc_user)
    m.send(stream)

    # finish, close the port
    print >> sys.stderr, "Done, have a nice day!"
    time.sleep(1)
    s.flush()
    s.flushInput()
    s.close()