scripts: west flash with stm32CubeProgrammer and ext-loader

Add the option to support an external loader for flashing
hex file to internal and external NOR flash using
the STM32CubProgrammer CLI with a  board_runner_args
"--extload=MX25LM51245G_STM32U585I-IOT02A.stldr"
The absolute path of the stldr file is added to the
stm32CubeProgrammer command.

Signed-off-by: Francois Ramu <francois.ramu@st.com>
This commit is contained in:
Francois Ramu 2024-01-31 17:48:08 +01:00 committed by Carles Cufí
commit 94d93af91f
2 changed files with 36 additions and 1 deletions

View file

@ -236,6 +236,10 @@ class RunnerCaps:
- reset: whether the runner supports a --reset option, which - reset: whether the runner supports a --reset option, which
resets the device after a flash operation is complete. resets the device after a flash operation is complete.
- extload: whether the runner supports a --extload option, which
must be given one time and is passed on to the underlying tool
that the runner wraps.
- tool_opt: whether the runner supports a --tool-opt (-O) option, which - tool_opt: whether the runner supports a --tool-opt (-O) option, which
can be given multiple times and is passed on to the underlying tool can be given multiple times and is passed on to the underlying tool
that the runner wraps. that the runner wraps.
@ -250,6 +254,7 @@ class RunnerCaps:
flash_addr: bool = False flash_addr: bool = False
erase: bool = False erase: bool = False
reset: bool = False reset: bool = False
extload: bool = False
tool_opt: bool = False tool_opt: bool = False
file: bool = False file: bool = False
@ -531,6 +536,10 @@ class ZephyrBinaryRunner(abc.ABC):
"Default action depends on each specific runner." "Default action depends on each specific runner."
if caps.reset else argparse.SUPPRESS)) if caps.reset else argparse.SUPPRESS))
parser.add_argument('--extload', dest='extload',
help=(cls.extload_help() if caps.extload
else argparse.SUPPRESS))
parser.add_argument('-O', '--tool-opt', dest='tool_opt', parser.add_argument('-O', '--tool-opt', dest='tool_opt',
default=[], action='append', default=[], action='append',
help=(cls.tool_opt_help() if caps.tool_opt help=(cls.tool_opt_help() if caps.tool_opt
@ -561,6 +570,8 @@ class ZephyrBinaryRunner(abc.ABC):
_missing_cap(cls, '--erase') _missing_cap(cls, '--erase')
if args.reset and not caps.reset: if args.reset and not caps.reset:
_missing_cap(cls, '--reset') _missing_cap(cls, '--reset')
if args.extload and not caps.extload:
_missing_cap(cls, '--extload')
if args.tool_opt and not caps.tool_opt: if args.tool_opt and not caps.tool_opt:
_missing_cap(cls, '--tool-opt') _missing_cap(cls, '--tool-opt')
if args.file and not caps.file: if args.file and not caps.file:
@ -649,6 +660,15 @@ class ZephyrBinaryRunner(abc.ABC):
target when multiple ones are available or target when multiple ones are available or
connected.''' connected.'''
@classmethod
def extload_help(cls) -> str:
''' Get the ArgParse help text for the --extload option.'''
return '''External loader to be used by stm32cubeprogrammer
to program the targeted external memory.
The runner requires the external loader (*.stldr) filename.
This external loader (*.stldr) must be located within
STM32CubeProgrammer/bin/ExternalLoader directory.'''
@classmethod @classmethod
def tool_opt_help(cls) -> str: def tool_opt_help(cls) -> str:
''' Get the ArgParse help text for the --tool-opt option.''' ''' Get the ArgParse help text for the --tool-opt option.'''

View file

@ -37,6 +37,7 @@ class STM32CubeProgrammerBinaryRunner(ZephyrBinaryRunner):
cli: Optional[Path], cli: Optional[Path],
use_elf: bool, use_elf: bool,
erase: bool, erase: bool,
extload: Optional[str],
tool_opt: List[str], tool_opt: List[str],
) -> None: ) -> None:
super().__init__(cfg) super().__init__(cfg)
@ -51,6 +52,12 @@ class STM32CubeProgrammerBinaryRunner(ZephyrBinaryRunner):
self._use_elf = use_elf self._use_elf = use_elf
self._erase = erase self._erase = erase
if extload:
p = STM32CubeProgrammerBinaryRunner._get_stm32cubeprogrammer_path().parent.resolve() / 'ExternalLoader'
self._extload = ['-el', str(p / extload)]
else:
self._extload = []
self._tool_opt: List[str] = list() self._tool_opt: List[str] = list()
for opts in [shlex.split(opt) for opt in tool_opt]: for opts in [shlex.split(opt) for opt in tool_opt]:
self._tool_opt += opts self._tool_opt += opts
@ -112,7 +119,7 @@ class STM32CubeProgrammerBinaryRunner(ZephyrBinaryRunner):
@classmethod @classmethod
def capabilities(cls): def capabilities(cls):
return RunnerCaps(commands={"flash"}, erase=True, tool_opt=True) return RunnerCaps(commands={"flash"}, erase=True, extload=True, tool_opt=True)
@classmethod @classmethod
def do_add_parser(cls, parser): def do_add_parser(cls, parser):
@ -151,6 +158,10 @@ class STM32CubeProgrammerBinaryRunner(ZephyrBinaryRunner):
help="Use ELF file when flashing instead of HEX file", help="Use ELF file when flashing instead of HEX file",
) )
@classmethod
def extload_help(cls) -> str:
return "External Loader for STM32_Programmer_CLI"
@classmethod @classmethod
def tool_opt_help(cls) -> str: def tool_opt_help(cls) -> str:
return "Additional options for STM32_Programmer_CLI" return "Additional options for STM32_Programmer_CLI"
@ -168,6 +179,7 @@ class STM32CubeProgrammerBinaryRunner(ZephyrBinaryRunner):
cli=args.cli, cli=args.cli,
use_elf=args.use_elf, use_elf=args.use_elf,
erase=args.erase, erase=args.erase,
extload=args.extload,
tool_opt=args.tool_opt, tool_opt=args.tool_opt,
) )
@ -192,6 +204,9 @@ class STM32CubeProgrammerBinaryRunner(ZephyrBinaryRunner):
cmd += ["--connect", connect_opts] cmd += ["--connect", connect_opts]
cmd += self._tool_opt cmd += self._tool_opt
if self._extload:
# external loader to come after the tool option in STM32CubeProgrammer
cmd += self._extload
# erase first if requested # erase first if requested
if self._erase: if self._erase: