Browse Source

scripts: west_commands: run: Add priority to run once config

Adds an optional priority parameter to the flash runner run once
configuration which allows for deciding upon which file should
ultimately be used

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
pull/80202/head
Jamie McCrae 1 year ago committed by Henrik Brix Andersen
parent
commit
a04dfc4ece
  1. 5
      scripts/schemas/board-schema.yml
  2. 5
      scripts/schemas/soc-schema.yml
  3. 105
      scripts/west_commands/run_common.py

5
scripts/schemas/board-schema.yml

@ -103,6 +103,11 @@ mapping: @@ -103,6 +103,11 @@ mapping:
runners:
type: map
mapping:
priority:
type: int
desc: |
Priority of this flash run once configuration. The highest value data will be used
instead of any with lower priorities. If omitted, will default to 10.
run_once:
type: map
desc: |

5
scripts/schemas/soc-schema.yml

@ -88,6 +88,11 @@ mapping: @@ -88,6 +88,11 @@ mapping:
runners:
type: map
mapping:
priority:
type: int
desc: |
Priority of this flash run once configuration. The highest value data will be used
instead of any with lower priorities. If omitted, will default to 0.
run_once:
type: map
desc: |

105
scripts/west_commands/run_common.py

@ -42,6 +42,10 @@ import zcmake @@ -42,6 +42,10 @@ import zcmake
# Don't change this, or output from argparse won't match up.
INDENT = ' ' * 2
IGNORED_RUN_ONCE_PRIORITY = -1
SOC_FILE_RUN_ONCE_DEFAULT_PRIORITY = 0
BOARD_FILE_RUN_ONCE_DEFAULT_PRIORITY = 10
if log.VERBOSE >= log.VERBOSE_NORMAL:
# Using level 1 allows sub-DEBUG levels of verbosity. The
# west.log module decides whether or not to actually print the
@ -96,6 +100,13 @@ class ImagesFlashed: @@ -96,6 +100,13 @@ class ImagesFlashed:
flashed: int = 0
total: int = 0
@dataclass
class SocBoardFilesProcessing:
filename: str
board: bool = False
priority: int = IGNORED_RUN_ONCE_PRIORITY
yaml: object = None
def command_verb(command):
return "flash" if command.name == "flash" else "debug"
@ -178,6 +189,10 @@ def do_run_common(command, user_args, user_runner_args, domain_file=None): @@ -178,6 +189,10 @@ def do_run_common(command, user_args, user_runner_args, domain_file=None):
# images for a given board.
board_image_count = defaultdict(ImagesFlashed)
highest_priority = IGNORED_RUN_ONCE_PRIORITY
highest_entry = None
check_files = []
if user_args.context:
dump_context(command, user_args, user_runner_args)
return
@ -223,48 +238,58 @@ def do_run_common(command, user_args, user_runner_args, domain_file=None): @@ -223,48 +238,58 @@ def do_run_common(command, user_args, user_runner_args, domain_file=None):
# Load board flash runner configuration (if it exists) and store
# single-use commands in a dictionary so that they get executed
# once per unique board name.
if cache['BOARD_DIR'] not in processed_boards and 'SOC_FULL_DIR' in cache:
soc_yaml_file = Path(cache['SOC_FULL_DIR']) / 'soc.yml'
board_yaml_file = Path(cache['BOARD_DIR']) / 'board.yml'
group_type = 'boards'
# Search for flash runner configuration, board takes priority over SoC
try:
with open(board_yaml_file, 'r') as f:
data_yaml = yaml.safe_load(f.read())
except FileNotFoundError:
continue
if 'runners' not in data_yaml:
# Check SoC file
group_type = 'qualifiers'
try:
with open(soc_yaml_file, 'r') as f:
data_yaml = yaml.safe_load(f.read())
except FileNotFoundError:
for directory in cache.get_list('SOC_DIRECTORIES'):
if directory not in processed_boards:
check_files.append(SocBoardFilesProcessing(Path(directory) / 'soc.yml'))
processed_boards.add(directory)
for directory in cache.get_list('BOARD_DIRECTORIES'):
if directory not in processed_boards:
check_files.append(SocBoardFilesProcessing(Path(directory) / 'board.yml', True))
processed_boards.add(directory)
for check in check_files:
try:
with open(check.filename, 'r') as f:
check.yaml = yaml.safe_load(f.read())
if 'runners' not in check.yaml:
continue
elif check.board is False and 'run_once' not in check.yaml['runners']:
continue
processed_boards.add(cache['BOARD_DIR'])
if 'runners' not in data_yaml or 'run_once' not in data_yaml['runners']:
continue
for cmd in data_yaml['runners']['run_once']:
for data in data_yaml['runners']['run_once'][cmd]:
for group in data['groups']:
run_first = bool(data['run'] == 'first')
if group_type == 'qualifiers':
targets = []
for target in group[group_type]:
# For SoC-based qualifiers, prepend to the beginning of the
# match to allow for matching any board name
targets.append('([^/]+)/' + target)
else:
targets = group[group_type]
used_cmds.append(UsedFlashCommand(cmd, targets, data['runners'], run_first))
if 'priority' in check.yaml['runners']:
check.priority = check.yaml['runners']['priority']
else:
check.priority = BOARD_FILE_RUN_ONCE_DEFAULT_PRIORITY if check.board is True else SOC_FILE_RUN_ONCE_DEFAULT_PRIORITY
if check.priority == highest_priority:
log.die("Duplicate flash run once configuration found with equal priorities")
elif check.priority > highest_priority:
highest_priority = check.priority
highest_entry = check
except FileNotFoundError:
continue
if highest_entry is not None:
group_type = 'boards' if highest_entry.board is True else 'qualifiers'
for cmd in highest_entry.yaml['runners']['run_once']:
for data in highest_entry.yaml['runners']['run_once'][cmd]:
for group in data['groups']:
run_first = bool(data['run'] == 'first')
if group_type == 'qualifiers':
targets = []
for target in group[group_type]:
# For SoC-based qualifiers, prepend to the beginning of the
# match to allow for matching any board name
targets.append('([^/]+)/' + target)
else:
targets = group[group_type]
used_cmds.append(UsedFlashCommand(cmd, targets, data['runners'], run_first))
# Reduce entries to only those having matching board names (either exact or with regex) and
# remove any entries with empty board lists

Loading…
Cancel
Save