Skip to content

Instantly share code, notes, and snippets.

@andygock
Created March 10, 2016 02:30
Show Gist options
  • Save andygock/b8319d2029ea7bc21380 to your computer and use it in GitHub Desktop.
Save andygock/b8319d2029ea7bc21380 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""
Multithreaded avrdude invoking script, to upload firmware
to RTU units.
Supports Windows, Mac, and Linux!
Designed to upload via multiple USB virtual serial ports at the
same time
It will upload to *ALL* detected serial ports! So make sure
you don't have any other virtual serial devices connected.
Usage: python Upload.py HEXFILE
"""
import serial, subprocess, threading, sys, os, glob
class Upload(threading.Thread):
def __init__(self,port,hex_file="RTU_2560.hex",threading=False):
super(Upload,self).__init__()
self._port = str(port)
self._hex_file = hex_file
self._threading = threading
def port(self):
return self._port
def run(self):
if self._threading:
# quiet upload when threaing, otherwise will conflict in console output
cmd = 'avrdude -q -q -c stk500v2 -p m2560 -P '+self._port+' -b 38400 -U flash:w:'+self._hex_file
else:
# verbose output
cmd = 'avrdude -c stk500v2 -p m2560 -P '+self._port+' -b 38400 -U flash:w:'+self._hex_file
print "Running: "+cmd
subprocess.call(cmd, shell=True)
return
def attempt_upload(hex_file, list_of_ports):
_ports_found = 0
# find out which ports can be opened, we want to count them and make a list
connectable_ports = []
for port in list_of_ports:
try:
ser = serial.Serial(port,38400,timeout=0.1)
except:
# could not connect to it, just try the next one
continue
if ser:
_ports_found += 1
connectable_ports.append(port)
ser.close()
# now connect to the ports and upload
for port in connectable_ports:
ser = serial.Serial(port,38400,timeout=0.1)
if ser:
ser.close()
print 'Detected ' + port
if _ports_found == 1:
# single upload, no threading
t = Upload(port, hex_file, False).start()
else:
# threaded operation
t = Upload(port, hex_file, True).start()
return _ports_found
# Main code
if __name__ == '__main__':
if len(sys.argv) >= 2:
hex_file = sys.argv[1]
ports_found = 0
if sys.platform == "win32" or sys.platform == "cygwin":
# Windows
ports = []
for n in range(2,99):
ports.append('COM'+str(n))
ports_found = attempt_upload(hex_file,ports)
elif sys.platform == "linux2":
# Linux
ports = []
for port in (glob.glob("/dev/ttyUSB*") + glob.glob("/dev/ttyACM*")):
ports.append(port)
ports_found = attempt_upload(hex_file,ports)
elif sys.platform == "darwin":
# MAC OSX
ports = []
for port in glob.glob("/dev/tty.usbserial-*"):
ports.append(port)
ports_found = attempt_upload(hex_file,ports)
else:
print "Operating system not supported!"
if not ports_found:
print "No serial ports found!"
else:
# No command line argument found
print "Upload.py HEXFILE"
exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment