#!/usr/bin/env python3 # Copyright (c) 2020 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Flash an EFR32 device. This is layered so that a caller can perform individual operations through an `Flasher` instance, or operations according to a command line. For `Flasher`, see the class documentation. For the parse_command() interface or standalone execution: usage: efr32_firmware_utils.py [-h] [--verbose] [--erase] [--application FILE] [--verify_application] [--reset] [--skip_reset] [--commander FILE] [--device DEVICE] [--serialno SERIAL] [--ip ADDRESS] Flash EFR32 device optional arguments: -h, --help show this help message and exit configuration: --verbose, -v Report more verbosely --commander FILE File name of the commander executable --device DEVICE, -d DEVICE Device family or platform to target --serialno SERIAL, -s SERIAL Serial number of device to flash --ip ADDRESS, -a ADDRESS Ip Address of the targeted flasher operations: --erase Erase device --application FILE Flash an image --verify_application, --verify-application Verify the image after flashing --reset Reset device after flashing --skip_reset, --skip-reset Do not reset device after flashing """ import sys import firmware_utils # Additional options that can be use to configure an `Flasher` # object (as dictionary keys) and/or passed as command line options. EFR32_OPTIONS = { # Configuration options define properties used in flashing operations. 'configuration': { # Tool configuration options. 'commander': { 'help': 'File name of the commander executable', 'default': 'commander', 'argparse': { 'metavar': 'FILE' }, 'verify': ['{commander}', '--version'], 'error': """\ Unable to execute {commander}. Please ensure that this tool is installed and available. See the EFR32 example README for installation instructions. """, }, 'device': { 'help': 'Device family or platform to target (EFR32 or MGM240)', 'default': None, 'alias': ['-d'], 'argparse': { 'metavar': 'DEVICE' }, }, 'serialno': { 'help': 'Serial number of device to flash', 'default': None, 'alias': ['-s'], 'argparse': { 'metavar': 'SERIAL' }, }, 'ip': { 'help': 'Ip Address of the probe connected to the target', 'default': None, 'alias': ['-a'], 'argparse': { 'metavar': 'ADDRESS' }, }, }, } class Flasher(firmware_utils.Flasher): """Manage efr32 flashing.""" def __init__(self, **options): super().__init__(platform='EFR32', module=__name__, **options) self.define_options(EFR32_OPTIONS) # Common command line arguments for commander device subcommands. DEVICE_ARGUMENTS = [{'optional': 'serialno'}, { 'optional': 'ip'}, {'optional': 'device'}] def erase(self): """Perform `commander device masserase`.""" return self.run_tool( 'commander', ['device', 'masserase', self.DEVICE_ARGUMENTS], name='Erase device') def verify(self, image): """Verify image.""" return self.run_tool( 'commander', ['verify', self.DEVICE_ARGUMENTS, image], name='Verify', pass_message='Verified', fail_message='Not verified', fail_level=2) def flash(self, image): """Flash image.""" return self.run_tool( 'commander', ['flash', self.DEVICE_ARGUMENTS, image], name='Flash') def reset(self): """Reset the device.""" return self.run_tool( 'commander', ['device', 'reset', self.DEVICE_ARGUMENTS], name='Reset') def actions(self): """Perform actions on the device according to self.option.""" self.log(3, 'Options:', self.option) if self.option.erase: if self.erase().err: return self if self.option.application: application = self.option.application if self.flash(application).err: return self if self.option.verify_application: if self.verify(application).err: return self if self.option.reset is None: self.option.reset = True if self.option.reset: if self.reset().err: return self return self if __name__ == '__main__': sys.exit(Flasher().flash_command(sys.argv))