1# Copyright (c) 2022 Renesas Electronics Corporation 2# 3# SPDX-License-Identifier: Apache-2.0 4 5'''Runner for flashing with ezFlashCLI.''' 6from runners.core import ZephyrBinaryRunner, RunnerCaps 7 8DEFAULT_EZFLASHCLI = "ezFlashCLI" 9 10class EzFlashCliBinaryRunner(ZephyrBinaryRunner): 11 '''Runner front-end for ezFlashCLI''' 12 13 def __init__(self, cfg, tool, sn, erase=False): 14 super().__init__(cfg) 15 self.bin_ = cfg.bin_file 16 17 self.tool = tool 18 self.sn_arg = ['-j', f'{sn}'] if sn is not None else [] 19 self.erase = bool(erase) 20 21 @classmethod 22 def name(cls): 23 return 'ezflashcli' 24 25 @classmethod 26 def capabilities(cls): 27 return RunnerCaps(commands={'flash'}, erase=True) 28 29 @classmethod 30 def do_add_parser(cls, parser): 31 parser.add_argument('--tool', default=DEFAULT_EZFLASHCLI, 32 help='ezFlashCLI path, default is ' 33 f'{DEFAULT_EZFLASHCLI}') 34 parser.add_argument('--sn', default=None, required=False, 35 help='J-Link probe serial number') 36 37 @classmethod 38 def do_create(cls, cfg, args): 39 return EzFlashCliBinaryRunner(cfg, tool=args.tool, sn=args.sn, 40 erase=args.erase) 41 42 def needs_product_header(self): 43 # Applications linked to code partition are meant to be run by MCUboot 44 # and do not require product header. Other applications and MCUboot itself 45 # are run by internal bootloader and thus require valid product header. 46 47 is_mcuboot = self.build_conf.getboolean('CONFIG_MCUBOOT') 48 uses_code_partition = self.build_conf.getboolean('CONFIG_USE_DT_CODE_PARTITION') 49 50 return is_mcuboot or not uses_code_partition 51 52 def program_bin(self): 53 54 if self.erase: 55 self.logger.info("Erasing flash...") 56 self.check_call([self.tool] + self.sn_arg + ["erase_flash"]) 57 58 self.logger.info(f"Flashing {self.bin_}...") 59 if self.needs_product_header(): 60 # Write product header and application image at fixed offset as required 61 # by internal bootloader. 62 self.check_call([self.tool] + self.sn_arg + ["image_flash", self.bin_]) 63 else: 64 load_offset = self.build_conf['CONFIG_FLASH_LOAD_OFFSET'] 65 self.check_call([self.tool] + self.sn_arg + ["write_flash", f'0x{load_offset:x}', self.bin_]) 66 67 def reset(self): 68 self.logger.info("Resetting...") 69 self.check_call([self.tool] + self.sn_arg + ["go"]) 70 71 def do_run(self, command, **kwargs): 72 self.require(self.tool) 73 self.ensure_output('bin') 74 self.program_bin() 75 self.reset() 76