diff options
author | Nick Sanders <nsanders@chromium.org> | 2017-09-14 16:16:10 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-10-25 01:38:45 -0700 |
commit | 28a5ad1646b2994853e310354b604547950a55c0 (patch) | |
tree | 066c2af5e0b90f03dc2a92eecfa2d20c32f5bca4 /extra | |
parent | c49d32a265ea76d9af55ccbcbda90e27748de1a3 (diff) | |
download | chrome-ec-28a5ad1646b2994853e310354b604547950a55c0.tar.gz |
servo: add usb updater
This updater combines console and firmware update commands to
update both RO and RW sections of servo_v4 and servo_micro.
BRANCH=None
BUG=b:37513705
TEST=updated firmware
Change-Id: I9f585c90f5849f8dd7c9d2e08111ffbd5770fd54
Signed-off-by: Nick Sanders <nsanders@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/668156
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'extra')
-rw-r--r-- | extra/tigertool/ecusb/stm32uart.py | 11 | ||||
-rw-r--r-- | extra/tigertool/ecusb/tiny_servo_common.py | 35 | ||||
-rwxr-xr-x | extra/tigertool/tigertool.py | 4 | ||||
l--------- | extra/usb_updater/ecusb | 1 | ||||
-rwxr-xr-x | extra/usb_updater/fw_update.py | 34 | ||||
-rwxr-xr-x | extra/usb_updater/servo_updater.py | 85 |
6 files changed, 138 insertions, 32 deletions
diff --git a/extra/tigertool/ecusb/stm32uart.py b/extra/tigertool/ecusb/stm32uart.py index 3f39b23faa..459ca8e90f 100644 --- a/extra/tigertool/ecusb/stm32uart.py +++ b/extra/tigertool/ecusb/stm32uart.py @@ -4,6 +4,8 @@ """Allow creation of uart/console interface via stm32 usb endpoint.""" +from __future__ import print_function + import os import select import sys @@ -33,7 +35,7 @@ class SuartError(Exception): class Suart(object): """Provide interface to stm32 serial usb endpoint.""" def __init__(self, vendor=0x18d1, product=0x501a, interface=0, - serialname=None, ftdi_context=None): + serialname=None, debuglog=False): """Suart contstructor. Initializes stm32 USB stream interface. @@ -42,8 +44,8 @@ class Suart(object): vendor: usb vendor id of stm32 device product: usb product id of stm32 device interface: interface number of stm32 device to use - serialname: n/a. Defaults to None. - ftdi_context: n/a. Defaults to None. + serialname: serial name to target. Defaults to None. + debuglog: chatty output. Defaults to False. Raises: SuartError: If init fails @@ -53,6 +55,7 @@ class Suart(object): self._ptyname = None self._rx_thread = None self._tx_thread = None + self._debuglog = debuglog self._susb = stm32usb.Susb(vendor=vendor, product=product, interface=interface, serialname=serialname) self._running = False @@ -83,6 +86,8 @@ class Suart(object): try: r = self._susb._read_ep.read(64, self._susb.TIMEOUT_MS) if r: + if self._debuglog: + print(''.join([chr(x) for x in r]), end='') os.write(self._ptym, r) # If we miss some characters on pty disconnect, that's fine. diff --git a/extra/tigertool/ecusb/tiny_servo_common.py b/extra/tigertool/ecusb/tiny_servo_common.py index a65697b116..c2a3992198 100644 --- a/extra/tigertool/ecusb/tiny_servo_common.py +++ b/extra/tigertool/ecusb/tiny_servo_common.py @@ -30,16 +30,25 @@ def log(output): sys.stdout.write('\n') sys.stdout.flush() -def check_usb(vidpid): +def check_usb(vidpid, serialname=None): """Check if |vidpid| is present on the system's USB. Args: vidpid: string representation of the usb vid:pid, eg. '18d1:2001' + serialname: serialname if specified. - Returns: True if found, Flase, otherwise. + Returns: True if found, False, otherwise. """ - if subprocess.call(['lsusb', '-d', vidpid], stdout=open('/dev/null', 'w')): + if serialname: + output = subprocess.check_output(['lsusb', '-v', '-d', vidpid]) + m = re.search(r'^\s*iSerial\s+\d+\s+%s$' % serialname, output, flags=re.M) + if m: + return True + return False + else: + if subprocess.call(['lsusb', '-d', vidpid], stdout=open('/dev/null', 'w')): + return False return True def check_usb_sn(vidpid): @@ -57,22 +66,24 @@ def check_usb_sn(vidpid): output = subprocess.check_output(['lsusb', '-v', '-d', vidpid]) m = re.search(r'^\s*iSerial\s+(.*)$', output, flags=re.M) if m: - return m.group(1) + return m.group(1) return None -def wait_for_usb_remove(vidpid, timeout=None): +def wait_for_usb_remove(vidpid, serialname=None, timeout=None): """Wait for USB device with vidpid to be removed. Wrapper for wait_for_usb below """ - wait_for_usb(vidpid, timeout=timeout, desiredpresence=False) + wait_for_usb(vidpid, serialname=serialname, + timeout=timeout, desiredpresence=False) -def wait_for_usb(vidpid, timeout=None, desiredpresence=True): +def wait_for_usb(vidpid, serialname=None, timeout=None, desiredpresence=True): """Wait for usb device with vidpid to be present/absent. Args: vidpid: string representation of the usb vid:pid, eg. '18d1:2001' + serialname: serialname if specificed. timeout: timeout in seconds, None for no timeout. desiredpresence: True for present, False for not present. @@ -81,7 +92,7 @@ def wait_for_usb(vidpid, timeout=None, desiredpresence=True): """ if timeout: finish = datetime.datetime.now() + datetime.timedelta(seconds=timeout) - while check_usb(vidpid) != desiredpresence: + while check_usb(vidpid, serialname) != desiredpresence: time.sleep(.1) if timeout: if datetime.datetime.now() > finish: @@ -118,7 +129,7 @@ def do_serialno(serialno, pty): 'Serial Number', 'Serial number set to %s but saved as %s.' % (serialno, sn)) -def setup_tinyservod(vidpid, interface, serialno=None): +def setup_tinyservod(vidpid, interface, serialname=None, debuglog=False): """Set up a pty Set up a pty to the ec console in order @@ -127,7 +138,8 @@ def setup_tinyservod(vidpid, interface, serialno=None): Args: vidpid: string vidpid of device to access. interface: not used. - serialno: string serial no of device requested, optional. + serialname: string serial name of device requested, optional. + debuglog: chatty printout (boolean) Returns: pty object @@ -138,7 +150,8 @@ def setup_tinyservod(vidpid, interface, serialno=None): vid = int(vidstr, 16) pid = int(pidstr, 16) suart = stm32uart.Suart(vendor=vid, product=pid, - interface=interface, serialname=serialno) + interface=interface, serialname=serialname, + debuglog=debuglog) suart.run() pty = pty_driver.ptyDriver(suart, []) diff --git a/extra/tigertool/tigertool.py b/extra/tigertool/tigertool.py index 8666fedbd0..c4ce86f01f 100755 --- a/extra/tigertool/tigertool.py +++ b/extra/tigertool/tigertool.py @@ -214,9 +214,9 @@ def main(argv): # Let's make sure there's a tigertail # If nothing found in 5 seconds, fail. - c.wait_for_usb(STM_VIDPID, 5.) + c.wait_for_usb(STM_VIDPID, timeout=5., serialname=opts.serialno) - pty = c.setup_tinyservod(STM_VIDPID, 0, serialno=opts.serialno) + pty = c.setup_tinyservod(STM_VIDPID, 0, serialname=opts.serialno) if opts.bus not in ('vbus', 'cc1', 'cc2'): c.log('Try --bus [vbus|cc1|cc2]') diff --git a/extra/usb_updater/ecusb b/extra/usb_updater/ecusb new file mode 120000 index 0000000000..c06ee0f51b --- /dev/null +++ b/extra/usb_updater/ecusb @@ -0,0 +1 @@ +../tigertool/ecusb/
\ No newline at end of file diff --git a/extra/usb_updater/fw_update.py b/extra/usb_updater/fw_update.py index 73393c8fb2..367c0cad14 100755 --- a/extra/usb_updater/fw_update.py +++ b/extra/usb_updater/fw_update.py @@ -5,6 +5,8 @@ # Upload firmware over USB +from __future__ import print_function + import argparse import array import json @@ -19,10 +21,10 @@ import usb debug = False def debuglog(msg): if debug: - print msg + print(msg) -def logoutput(msg): - print msg +def log(msg): + print(msg) sys.stdout.flush() @@ -189,7 +191,7 @@ class Supdate(object): read = self.wr_command(cmd, read_count=4) if len(read) == 4: - print "Finished flashing" + log("Finished flashing") return raise Exception("Update", "Stop failed [%s]" % read) @@ -212,7 +214,7 @@ class Supdate(object): region, self._brdcfg['regions'][region][0], offset)) length = self._brdcfg['regions'][region][1] - print "Sending" + log("Sending") # Go to the correct region in the ec.bin file. self._binfile.seek(offset) @@ -246,7 +248,7 @@ class Supdate(object): self.wr_command(data, read_count=0) break except: - print "Timeout fail" + log("Timeout fail") todo -= packetsize # Done with this packet, move to the next one. length -= pagesize @@ -285,8 +287,8 @@ class Supdate(object): raise Exception("Update", "Protocol version 0 not supported") elif len(read) == expected: base, version = struct.unpack(">II", read) - print "Update protocol v. %d" % version - print "Available flash region base: %x" % base + log("Update protocol v. %d" % version) + log("Available flash region base: %x" % base) else: raise Exception("Update", "Start command returned %d bytes" % len(read)) @@ -302,7 +304,7 @@ class Supdate(object): if (self._offset >= self._brdcfg['regions'][region][0]) and \ (self._offset < (self._brdcfg['regions'][region][0] + \ self._brdcfg['regions'][region][1])): - print "Active region: %s" % region + log("Active region: %s" % region) self._region = region @@ -333,26 +335,26 @@ class Supdate(object): if debug: pprint(data) - print "Board is %s" % self._brdcfg['board'] + log("Board is %s" % self._brdcfg['board']) # Cast hex strings to int. self._brdcfg['flash'] = int(self._brdcfg['flash'], 0) self._brdcfg['vid'] = int(self._brdcfg['vid'], 0) self._brdcfg['pid'] = int(self._brdcfg['pid'], 0) - print "Flash Base is %x" % self._brdcfg['flash'] + log("Flash Base is %x" % self._brdcfg['flash']) self._flashsize = 0 for region in self._brdcfg['regions']: base = int(self._brdcfg['regions'][region][0], 0) length = int(self._brdcfg['regions'][region][1], 0) - print "region %s\tbase:0x%08x size:0x%08x" % ( - region, base, length) + log("region %s\tbase:0x%08x size:0x%08x" % ( + region, base, length)) self._flashsize += length # Convert these to int because json doesn't support hex. self._brdcfg['regions'][region][0] = base self._brdcfg['regions'][region][1] = length - print "Flash Size: 0x%x" % self._flashsize + log("Flash Size: 0x%x" % self._flashsize) def load_file(self, binfile): """Open and verify size of the target ec.bin file. @@ -405,11 +407,11 @@ def main(): # Start transfer and erase. p.start() # Upload the bin file - print "Uploading %s" % binfile + log("Uploading %s" % binfile) p.write_file() # Finalize - print "Done. Finalizing." + log("Done. Finalizing.") p.stop() if __name__ == "__main__": diff --git a/extra/usb_updater/servo_updater.py b/extra/usb_updater/servo_updater.py new file mode 100755 index 0000000000..0f7d640c39 --- /dev/null +++ b/extra/usb_updater/servo_updater.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +# Copyright 2016 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from __future__ import print_function + +import argparse +import errno +import os +import subprocess +import time + +import json +import fw_update +import ecusb.tiny_servo_common as c + + +def flash(brdfile, serialno, binfile): + p = fw_update.Supdate() + p.load_board(brdfile) + p.connect_usb(serialname=serialno) + p.load_file(binfile) + + # Start transfer and erase. + p.start() + # Upload the bin file + print("Uploading %s" % binfile) + p.write_file() + + # Finalize + print("Done. Finalizing.") + p.stop() + + +def select(vidpid, serialno, region, debuglog=False): + if region not in ["rw", "ro"]: + raise Exception("Region must be ro or rw") + + # Make sure device is up + c.wait_for_usb(vidpid, serialname=serialno) + + # make a console + pty = c.setup_tinyservod(vidpid, 0, serialname=serialno, debuglog=debuglog) + + cmd = "sysjump %s\nreboot" % region + pty._issue_cmd(cmd) + time.sleep(1) + pty.close() + + +def main(): + parser = argparse.ArgumentParser(description="Image a servo micro device") + parser.add_argument('-s', '--serialno', type=str, + help="serial number to program", default=None) + parser.add_argument('-b', '--board', type=str, + help="Board configuration json file", default="servo_v4.json") + parser.add_argument('-f', '--file', type=str, + help="Complete ec.bin file", default="servo_v4.bin") + parser.add_argument('-v', '--verbose', action="store_true", + help="Chatty output") + + args = parser.parse_args() + + brdfile = args.board + binfile = args.file + serialno = args.serialno + debuglog = (args.verbose is True) + + with open(brdfile) as data_file: + data = json.load(data_file) + + vidpid = "%04x:%04x" % (int(data['vid'], 0), int(data['pid'], 0)) + + select(vidpid, serialno, "ro", debuglog=debuglog) + + flash(brdfile, serialno, binfile) + + select(vidpid, serialno, "rw", debuglog=debuglog) + + flash(brdfile, serialno, binfile) + +if __name__ == "__main__": + main() + |