Skip to content

Commit 6dacc14

Browse files
gmarullkartben
authored andcommitted
scripts: west_commands: runners: add sftool runner
So we can flash using sftool. Ref. https://github.com/OpenSiFli/sftool. Signed-off-by: Gerard Marull-Paretas <[email protected]>
1 parent 9a1bb99 commit 6dacc14

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

scripts/west_commands/runners/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def _import_runner_module(runner_name):
5656
'renode',
5757
'renode-robot',
5858
'rfp',
59+
'sftool',
5960
'silabs_commander',
6061
'spi_burn',
6162
'spsdk',
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Copyright (c) 2025 Core Devices LLC
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import argparse
5+
import shlex
6+
7+
from runners.core import RunnerCaps, RunnerConfig, ZephyrBinaryRunner
8+
9+
10+
class SftoolRunner(ZephyrBinaryRunner):
11+
"""Runner front-end for sftool CLI."""
12+
13+
def __init__(
14+
self,
15+
cfg: RunnerConfig,
16+
chip: str,
17+
port: str,
18+
erase: bool,
19+
dt_flash: bool,
20+
tool_opt: list[str],
21+
) -> None:
22+
super().__init__(cfg)
23+
24+
self._chip = chip
25+
self._port = port
26+
self._erase = erase
27+
self._dt_flash = dt_flash
28+
29+
self._tool_opt: list[str] = []
30+
for opts in [shlex.split(opt) for opt in tool_opt]:
31+
self._tool_opt += opts
32+
33+
@classmethod
34+
def name(cls):
35+
return "sftool"
36+
37+
@classmethod
38+
def capabilities(cls):
39+
return RunnerCaps(commands={"flash"}, erase=True, flash_addr=True, file=True, tool_opt=True)
40+
41+
@classmethod
42+
def do_add_parser(cls, parser):
43+
parser.add_argument(
44+
"--chip",
45+
type=str,
46+
required=True,
47+
help="Target chip, e.g. SF32LB52",
48+
)
49+
50+
parser.add_argument(
51+
"--port",
52+
type=str,
53+
required=True,
54+
help="Serial port device, e.g. /dev/ttyUSB0",
55+
)
56+
57+
@classmethod
58+
def do_create(cls, cfg: RunnerConfig, args: argparse.Namespace) -> "SftoolRunner":
59+
return SftoolRunner(
60+
cfg,
61+
chip=args.chip,
62+
port=args.port,
63+
erase=args.erase,
64+
dt_flash=args.dt_flash,
65+
tool_opt=args.tool_opt,
66+
)
67+
68+
def do_run(self, command: str, **kwargs):
69+
sftool = self.require("sftool")
70+
71+
cmd = [sftool, "--chip", self._chip, "--port", self._port]
72+
cmd += self._tool_opt
73+
74+
if self._erase:
75+
self.check_call(cmd + ["erase_flash"])
76+
77+
if self.cfg.file:
78+
self.check_call(cmd + ["write_flash", self.cfg.file])
79+
else:
80+
if self.cfg.bin_file and self._dt_flash:
81+
addr = self.flash_address_from_build_conf(self.build_conf)
82+
self.check_call(cmd + ["write_flash", f"{self.cfg.bin_file}@0x{addr:08x}"])
83+
elif self.cfg.hex_file:
84+
self.check_call(cmd + ["write_flash", self.cfg.hex_file])
85+
else:
86+
raise RuntimeError("No file available for flashing")

scripts/west_commands/tests/test_imports.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def test_runner_imports():
4747
'renode',
4848
'renode-robot',
4949
'rfp',
50+
'sftool',
5051
'silabs_commander',
5152
'spi_burn',
5253
'spsdk',

0 commit comments

Comments
 (0)