1# Copyright (c) 2019 Thomas Kupper <thomas.kupper@gmail.com> 2# 3# SPDX-License-Identifier: Apache-2.0 4 5'''Runner for flashing with stm32flash.''' 6 7from os import path 8import platform 9 10from runners.core import ZephyrBinaryRunner, RunnerCaps 11 12DEFAULT_DEVICE = '/dev/ttyUSB0' 13if platform.system() == 'Darwin': 14 DEFAULT_DEVICE = '/dev/tty.SLAB_USBtoUART' 15 16class Stm32flashBinaryRunner(ZephyrBinaryRunner): 17 '''Runner front-end for stm32flash.''' 18 19 def __init__(self, cfg, device, action='write', baud=57600, 20 force_binary=False, start_addr=0, exec_addr=None, 21 serial_mode='8e1', reset=False, verify=False): 22 super().__init__(cfg) 23 24 self.device = device 25 self.action = action 26 self.baud = baud 27 self.force_binary = force_binary 28 self.start_addr = start_addr 29 self.exec_addr = exec_addr 30 self.serial_mode = serial_mode 31 self.reset = reset 32 self.verify = verify 33 34 @classmethod 35 def name(cls): 36 return 'stm32flash' 37 38 @classmethod 39 def capabilities(cls): 40 return RunnerCaps(commands={'flash'}, reset=True) 41 42 @classmethod 43 def do_add_parser(cls, parser): 44 45 # required argument(s) 46 # none for now 47 48 # optional argument(s) 49 parser.add_argument('--device', default=DEFAULT_DEVICE, required=False, 50 help='serial port to flash, default \'' + DEFAULT_DEVICE + '\'') 51 52 parser.add_argument('--action', default='write', required=False, 53 choices=['erase', 'info', 'start', 'write'], 54 help='erase / get device info / start execution / write flash') 55 56 parser.add_argument('--baud-rate', default='57600', required=False, 57 choices=['1200', '1800', '2400', '4800', '9600', '19200', 58 '38400', '57600', '115200', '230400', '256000', '460800', 59 '500000', '576000', '921600', '1000000', '1500000', '2000000'], 60 help='serial baud rate, default \'57600\'') 61 62 parser.add_argument('--force-binary', required=False, action='store_true', 63 help='force the binary parser') 64 65 parser.add_argument('--start-addr', default=0, required=False, 66 help='specify start address for write operation, default \'0\'') 67 68 parser.add_argument('--execution-addr', default=None, required=False, 69 help='start execution at specified address, default \'0\' \ 70 which means start of flash') 71 72 parser.add_argument('--serial-mode', default='8e1', required=False, 73 help='serial port mode, default \'8e1\'') 74 75 parser.add_argument('--verify', default=False, required=False, action='store_true', 76 help='verify writes, default False') 77 78 parser.set_defaults(reset=False) 79 80 @classmethod 81 def do_create(cls, cfg, args): 82 return Stm32flashBinaryRunner(cfg, device=args.device, action=args.action, 83 baud=args.baud_rate, force_binary=args.force_binary, 84 start_addr=args.start_addr, exec_addr=args.execution_addr, 85 serial_mode=args.serial_mode, reset=args.reset, verify=args.verify) 86 87 def do_run(self, command, **kwargs): 88 self.require('stm32flash') 89 self.ensure_output('bin') 90 91 bin_name = self.cfg.bin_file 92 bin_size = path.getsize(bin_name) 93 94 cmd_flash = ['stm32flash', '-b', self.baud, 95 '-m', self.serial_mode] 96 97 action = self.action.lower() 98 99 if action == 'info': 100 # show device information and exit 101 msg_text = "get device info from {}".format(self.device) 102 103 elif action == 'erase': 104 # erase flash 105 #size_aligned = (int(bin_size) >> 12) + 1 << 12 106 size_aligned = (int(bin_size) & 0xfffff000) + 4096 107 msg_text = "erase {} bit starting at {}".format(size_aligned, self.start_addr) 108 cmd_flash.extend([ 109 '-S', str(self.start_addr) + ":" + str(size_aligned), '-o']) 110 111 elif action == 'start': 112 # start execution 113 msg_text = "start code execution at {}".format(self.exec_addr) 114 if self.exec_addr: 115 if self.exec_addr == 0 or self.exec_addr.lower() == '0x0': 116 msg_text += " (flash start)" 117 else: 118 self.exec_addr = 0 119 cmd_flash.extend([ 120 '-g', str(self.exec_addr)]) 121 122 elif action == 'write': 123 # flash binary file 124 msg_text = "write {} bytes starting at {}".format(bin_size, self.start_addr) 125 cmd_flash.extend([ 126 '-S', str(self.start_addr) + ":" + str(bin_size), 127 '-w', bin_name]) 128 129 if self.exec_addr: 130 cmd_flash.extend(['-g', self.exec_addr]) 131 132 if self.force_binary: 133 cmd_flash.extend(['-f']) 134 135 if self.reset: 136 cmd_flash.extend(['-R']) 137 138 if self.verify: 139 cmd_flash.extend(['-v']) 140 141 else: 142 msg_text = "invalid action \'{}\' passed!".format(action) 143 self.logger.error('Invalid action \'{}\' passed!'.format(action)) 144 return -1 145 146 cmd_flash.extend([self.device]) 147 self.logger.info("Board: " + msg_text) 148 self.check_call(cmd_flash) 149 self.logger.info('Board: finished \'{}\' .'.format(action)) 150