diff options
author | Todd Broch <tbroch@chromium.org> | 2014-08-18 17:53:35 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-08-20 21:07:26 +0000 |
commit | f8fbd1e440f87502b85e71c14719b58cfa79ebea (patch) | |
tree | f49100c6cb7a0089da65742a7bde0b31db8545e2 | |
parent | 6a99f7d0a432a1ab040b0548cfa32259b90e804b (diff) | |
download | chrome-ec-f8fbd1e440f87502b85e71c14719b58cfa79ebea.tar.gz |
flash_pd.py: Add retries for commands for collision resilience.
The original version of the script worked but as the USB PD protocol
SM has been enhanced to handle more complicated scenarios the
occurrence of collisions on the baseband comm has grown and script
needs to account for that.
Script now checks status of ACK from zinger 'DONE 0' and retries two
additional times for commands that failed. If those three attempts
are unsuccessful script raises exception and quits.
Also added some more logging around retries and progress of chunk
writes.
BRANCH=none
BUG=chrome-os-partner:30135
TEST=manual, util/flash_pd.py build/zinger/ec.RW.flat succeeds in
programming zinger even in light of some retries.
Change-Id: Iaa8a22c2510ea5f4ebd92e1715be5fe062e13c61
Signed-off-by: Todd Broch <tbroch@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/213131
Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rwxr-xr-x | util/flash_pd.py | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/util/flash_pd.py b/util/flash_pd.py index 2ae64b730e..f6ea1f2230 100755 --- a/util/flash_pd.py +++ b/util/flash_pd.py @@ -2,7 +2,11 @@ # Copyright (c) 2014 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. -"""Flash PD PSU RW firmware over the USBPD comm channel using console.""" +"""Flash PD PSU RW firmware over the USBPD comm channel using console. + + Example: + util/flash_pd.py ./build/zinger/ec.RW.flat +""" import array import errno @@ -118,21 +122,38 @@ class FlashPD(client.ServoClient): if done or time.time() > deadline: break if not done: - logging.error('\"%s\" missing', val) + logging.debug("Expect '%s' missing", val) return (done, l) - def flash_command(self, cmd, expect='DONE'): + def flash_command(self, cmd, expect='DONE 0', retries=2): """Send PD Flash command and interrogate output. Args: - cmd : string of 'pd port flash' command to execute - expect : string of expected response after 'cmd' + cmd : string of 'pd port flash' command to execute + expect : string of expected response after 'cmd' + retries : integer number of times to repeat command if it fails. Returns: - found : boolean, whether response matches expected. + tuple : + found : boolean, whether response matches expected. + line : string of line returned by expect method. + + Raises: + FlashPDError: if command failed to match expected return string after + retries. """ - self._serial.write('pd %d flash %s\n' % (self._options.multiport, cmd)) - (found, line) = self.expect(expect) + tries = retries + 1 + for i in xrange(tries): + self._serial.write('pd %d flash %s\n' % (self._options.multiport, cmd)) + (found, line) = self.expect(expect) + if i: + time.sleep(1) + logging.debug("pd flash cmd Retry%d for '%s'", i, cmd) + if found: + break + if (i + 1) == tries and not found: + raise FlashPDError("Failed pd flash cmd: '%s' after %d retries\n" % + (cmd, retries)) return (found, line) def get_version(self): @@ -154,6 +175,16 @@ class FlashPD(client.ServoClient): raise FlashPDError('Unable to determine PD FW version') return m.group(1) + def reboot(self): + """Reboot PSU. + + Use 'version' to poll for success after DONE encountered. + Raises: + FlashPDError : If unable to reboot + """ + self.flash_command('reboot', expect=r'DONE', retries=0) + self.flash_command('version', retries=10) + def flash_pd(options): """Flash power delivery firmware.""" @@ -182,9 +213,7 @@ def flash_pd(options): # reset flashed hash to reboot in RO ec.flash_command('hash' + ' 00000000' * 5) # reboot in RO - ec.flash_command('reboot') - # delay to give time to reboot - time.sleep(1.5) + ec.reboot() # erase all RW partition ec.flash_command('erase') @@ -199,7 +228,7 @@ def flash_pd(options): logging.info('Successfully erased flash.') if options.eraseonly: - ec.flash_command('reboot') + ec.reboot() logging.info('After erase, FW version is %s', ec.get_version()) return @@ -208,13 +237,13 @@ def flash_pd(options): chunk = words[i * 6: (i + 1) * 6] cmd = ' '.join(['%08x' % (w) for w in chunk]) ec.flash_command(cmd) + if not i % 0x10: + logging.info('Chunk %d of %d done.', i, len(words) / 6) # write new firmware hash ec.flash_command('hash ' + sha_str) # reboot in RW - ec.flash_command('reboot') - # delay for reboot - time.sleep(1.5) + ec.reboot() logging.info('Flashing DONE.') logging.info('SHA-1: %s', sha_str) |