mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 16:41:55 +00:00
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>
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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, [])
|
||||
|
||||
|
||||
@@ -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]')
|
||||
|
||||
1
extra/usb_updater/ecusb
Symbolic link
1
extra/usb_updater/ecusb
Symbolic link
@@ -0,0 +1 @@
|
||||
../tigertool/ecusb/
|
||||
@@ -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__":
|
||||
|
||||
85
extra/usb_updater/servo_updater.py
Executable file
85
extra/usb_updater/servo_updater.py
Executable file
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user