mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-03 05:43:45 +00:00
Require all implementations to provide a do_create(), a new ZephyrBinaryRunner abstract class method, and make create() itself concrete. This allows us to enforce common conventions related to individual runner capabilities as each runner provides to the core via RunnerCaps. For now, just enforce that: - common options related to capabilities are always added, so runners can't reuse them for different ends - common options provided for runners which don't support them emit sensible error messages that should be easy to diagnose and support Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
150 lines
5.5 KiB
Python
150 lines
5.5 KiB
Python
# Copyright (c) 2019 Thomas Kupper <thomas.kupper@gmail.com>
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
'''Runner for flashing with stm32flash.'''
|
|
|
|
from os import path
|
|
import platform
|
|
|
|
from runners.core import ZephyrBinaryRunner, RunnerCaps
|
|
|
|
DEFAULT_DEVICE = '/dev/ttyUSB0'
|
|
if platform.system() == 'Darwin':
|
|
DEFAULT_DEVICE = '/dev/tty.SLAB_USBtoUART'
|
|
|
|
class Stm32flashBinaryRunner(ZephyrBinaryRunner):
|
|
'''Runner front-end for stm32flash.'''
|
|
|
|
def __init__(self, cfg, device, action='write', baud=57600,
|
|
force_binary=False, start_addr=0, exec_addr=None,
|
|
serial_mode='8e1', reset=False, verify=False):
|
|
super().__init__(cfg)
|
|
|
|
self.device = device
|
|
self.action = action
|
|
self.baud = baud
|
|
self.force_binary = force_binary
|
|
self.start_addr = start_addr
|
|
self.exec_addr = exec_addr
|
|
self.serial_mode = serial_mode
|
|
self.reset = reset
|
|
self.verify = verify
|
|
|
|
@classmethod
|
|
def name(cls):
|
|
return 'stm32flash'
|
|
|
|
@classmethod
|
|
def capabilities(cls):
|
|
return RunnerCaps(commands={'flash'})
|
|
|
|
@classmethod
|
|
def do_add_parser(cls, parser):
|
|
|
|
# required argument(s)
|
|
# none for now
|
|
|
|
# optional argument(s)
|
|
parser.add_argument('--device', default=DEFAULT_DEVICE, required=False,
|
|
help='serial port to flash, default \'' + DEFAULT_DEVICE + '\'')
|
|
|
|
parser.add_argument('--action', default='write', required=False,
|
|
choices=['erase', 'info', 'start', 'write'],
|
|
help='erase / get device info / start execution / write flash')
|
|
|
|
parser.add_argument('--baud-rate', default='57600', required=False,
|
|
choices=['1200', '1800', '2400', '4800', '9600', '19200',
|
|
'38400', '57600', '115200', '230400', '256000', '460800',
|
|
'500000', '576000', '921600', '1000000', '1500000', '2000000'],
|
|
help='serial baud rate, default \'57600\'')
|
|
|
|
parser.add_argument('--force-binary', required=False, action='store_true',
|
|
help='force the binary parser')
|
|
|
|
parser.add_argument('--start-addr', default=0, required=False,
|
|
help='specify start address for write operation, default \'0\'')
|
|
|
|
parser.add_argument('--execution-addr', default=None, required=False,
|
|
help='start execution at specified address, default \'0\' \
|
|
which means start of flash')
|
|
|
|
parser.add_argument('--serial-mode', default='8e1', required=False,
|
|
help='serial port mode, default \'8e1\'')
|
|
|
|
parser.add_argument('--reset', default=False, required=False, action='store_true',
|
|
help='reset device at exit, default False')
|
|
|
|
parser.add_argument('--verify', default=False, required=False, action='store_true',
|
|
help='verify writes, default False')
|
|
|
|
@classmethod
|
|
def do_create(cls, cfg, args):
|
|
return Stm32flashBinaryRunner(cfg, device=args.device, action=args.action,
|
|
baud=args.baud_rate, force_binary=args.force_binary,
|
|
start_addr=args.start_addr, exec_addr=args.execution_addr,
|
|
serial_mode=args.serial_mode, reset=args.reset, verify=args.verify)
|
|
|
|
def do_run(self, command, **kwargs):
|
|
self.require('stm32flash')
|
|
|
|
bin_name = self.cfg.bin_file
|
|
bin_size = path.getsize(bin_name)
|
|
|
|
cmd_flash = ['stm32flash', '-b', self.baud,
|
|
'-m', self.serial_mode]
|
|
|
|
action = self.action.lower()
|
|
|
|
if action == 'info':
|
|
# show device information and exit
|
|
msg_text = "get device info from {}".format(self.device)
|
|
|
|
elif action == 'erase':
|
|
# erase flash
|
|
#size_aligned = (int(bin_size) >> 12) + 1 << 12
|
|
size_aligned = (int(bin_size) & 0xfffff000) + 4096
|
|
msg_text = "erase {} bit starting at {}".format(size_aligned, self.start_addr)
|
|
cmd_flash.extend([
|
|
'-S', str(self.start_addr) + ":" + str(size_aligned), '-o'])
|
|
|
|
elif action == 'start':
|
|
# start execution
|
|
msg_text = "start code execution at {}".format(self.exec_addr)
|
|
if self.exec_addr:
|
|
if self.exec_addr == 0 or self.exec_addr.lower() == '0x0':
|
|
msg_text += " (flash start)"
|
|
else:
|
|
self.exec_addr = 0
|
|
cmd_flash.extend([
|
|
'-g', str(self.exec_addr)])
|
|
|
|
elif action == 'write':
|
|
# flash binary file
|
|
msg_text = "write {} bytes starting at {}".format(bin_size, self.start_addr)
|
|
cmd_flash.extend([
|
|
'-S', str(self.start_addr) + ":" + str(bin_size),
|
|
'-w', bin_name])
|
|
|
|
if self.exec_addr:
|
|
cmd_flash.extend(['-g', self.exec_addr])
|
|
|
|
if self.force_binary:
|
|
cmd_flash.extend(['-f'])
|
|
|
|
if self.reset:
|
|
cmd_flash.extend(['-R'])
|
|
|
|
if self.verify:
|
|
cmd_flash.extend(['-v'])
|
|
|
|
else:
|
|
msg_text = "invalid action \'{}\' passed!".format(action)
|
|
self.logger.error('Invalid action \'{}\' passed!'.format(action))
|
|
return -1
|
|
|
|
cmd_flash.extend([self.device])
|
|
self.logger.info("Board: " + msg_text)
|
|
self.check_call(cmd_flash)
|
|
self.logger.info('Board: finished \'{}\' .'.format(action))
|