zephyr/scripts/west_commands/tests/test_stm32cubeprogrammer.py
Mathieu Choplain 4dc8acc6d1 scripts: west: runners: stm32cubeprogrammer: add start address argument
Add new '--start-address' argument to the STM32CubeProgrammer west runner.
This argument can be used to specify an address from which the MCU should
start executing, instead of relying on the default value in CubeProgrammer.

Also update STM32CubeProgrammer runner tests to support new argument.

Signed-off-by: Mathieu Choplain <mathieu.choplain@st.com>
2024-12-17 23:15:13 +01:00

462 lines
12 KiB
Python

# Copyright (c) 2020 Teslabs Engineering S.L.
#
# SPDX-License-Identifier: Apache-2.0
import argparse
from pathlib import Path
from unittest.mock import patch, call
import pytest
from runners.stm32cubeprogrammer import STM32CubeProgrammerBinaryRunner
from conftest import RC_KERNEL_HEX, RC_KERNEL_ELF
CLI_PATH = Path("STM32_Programmer_CLI")
"""Default CLI path used in tests."""
HOME_PATH = Path("/home", "test")
"""Home path (used for Linux system CLI path)."""
PROGRAMFILESX86_PATH = Path("C:", "Program Files (x86)")
"""Program files x86 path (used for Windows system CLI path)."""
ENVIRON = {
"PROGRAMFILES(X86)": str(PROGRAMFILESX86_PATH),
}
"""Environment (used for Windows system CLI path)."""
LINUX_CLI_PATH = (
HOME_PATH
/ "STMicroelectronics"
/ "STM32Cube"
/ "STM32CubeProgrammer"
/ "bin"
/ "STM32_Programmer_CLI"
)
"""Linux CLI path."""
WINDOWS_CLI_PATH = (
PROGRAMFILESX86_PATH
/ "STMicroelectronics"
/ "STM32Cube"
/ "STM32CubeProgrammer"
/ "bin"
/ "STM32_Programmer_CLI.exe"
)
"""Windows CLI path."""
MACOS_CLI_PATH = (
Path("/Applications")
/ "STMicroelectronics"
/ "STM32Cube"
/ "STM32CubeProgrammer"
/ "STM32CubeProgrammer.app"
/ "Contents"
/ "MacOs"
/ "bin"
/ "STM32_Programmer_CLI"
)
"""macOS CLI path."""
TEST_CASES = (
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": None,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": 0x8001000,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd",
"--download",
RC_KERNEL_HEX,
"--start",
"0x8001000"
],
],
},
{
"port": "swd",
"frequency": "4000",
"reset_mode": None,
"start_address": None,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd freq=4000",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": "hw",
"start_address": None,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd reset=HWrst",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": "sw",
"start_address": None,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd reset=SWrst",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": "core",
"start_address": None,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd reset=Crst",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": None,
"conn_modifiers": "br=115200 sn=TEST",
"cli": CLI_PATH,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd br=115200 sn=TEST",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": None,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": True,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd",
"--download",
RC_KERNEL_ELF,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": None,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": False,
"erase": True,
"extload": None,
"tool_opt": [],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[str(CLI_PATH), "--connect", "port=swd", "--erase", "all",],
[
str(CLI_PATH),
"--connect",
"port=swd",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": None,
"conn_modifiers": None,
"cli": CLI_PATH,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": ["--skipErase"],
"system": "",
"cli_path": str(CLI_PATH),
"calls": [
[
str(CLI_PATH),
"--connect",
"port=swd",
"--skipErase",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": None,
"conn_modifiers": None,
"cli": None,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "Linux",
"cli_path": str(LINUX_CLI_PATH),
"calls": [
[
str(LINUX_CLI_PATH),
"--connect",
"port=swd",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": None,
"conn_modifiers": None,
"cli": None,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "Darwin",
"cli_path": str(MACOS_CLI_PATH),
"calls": [
[
str(MACOS_CLI_PATH),
"--connect",
"port=swd",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
{
"port": "swd",
"frequency": None,
"reset_mode": None,
"start_address": None,
"conn_modifiers": None,
"cli": None,
"use_elf": False,
"erase": False,
"extload": None,
"tool_opt": [],
"system": "Windows",
"cli_path": str(WINDOWS_CLI_PATH),
"calls": [
[
str(WINDOWS_CLI_PATH),
"--connect",
"port=swd",
"--download",
RC_KERNEL_HEX,
"--start",
],
],
},
)
"""Test cases."""
@pytest.mark.parametrize("tc", TEST_CASES)
@patch("runners.stm32cubeprogrammer.platform.system")
@patch("runners.stm32cubeprogrammer.Path.home", return_value=HOME_PATH)
@patch("runners.stm32cubeprogrammer.Path.exists", return_value=True)
@patch.dict("runners.stm32cubeprogrammer.os.environ", ENVIRON)
@patch("runners.core.ZephyrBinaryRunner.require")
@patch("runners.stm32cubeprogrammer.STM32CubeProgrammerBinaryRunner.check_call")
def test_stm32cubeprogrammer_init(
check_call, require, path_exists, path_home, system, tc, runner_config
):
"""Tests that ``STM32CubeProgrammerBinaryRunner`` class can be initialized
and that ``flash`` command works as expected.
"""
system.return_value = tc["system"]
runner = STM32CubeProgrammerBinaryRunner(
cfg=runner_config,
port=tc["port"],
frequency=tc["frequency"],
reset_mode=tc["reset_mode"],
start_address=tc["start_address"],
conn_modifiers=tc["conn_modifiers"],
cli=tc["cli"],
use_elf=tc["use_elf"],
erase=tc["erase"],
extload=tc["extload"],
tool_opt=tc["tool_opt"],
)
runner.run("flash")
require.assert_called_with(tc["cli_path"])
assert check_call.call_args_list == [call(x) for x in tc["calls"]]
@pytest.mark.parametrize("tc", TEST_CASES)
@patch("runners.stm32cubeprogrammer.platform.system")
@patch("runners.stm32cubeprogrammer.Path.home", return_value=HOME_PATH)
@patch("runners.stm32cubeprogrammer.Path.exists", return_value=True)
@patch.dict("runners.stm32cubeprogrammer.os.environ", ENVIRON)
@patch("runners.core.ZephyrBinaryRunner.require")
@patch("runners.stm32cubeprogrammer.STM32CubeProgrammerBinaryRunner.check_call")
def test_stm32cubeprogrammer_create(
check_call, require, path_exists, path_home, system, tc, runner_config
):
"""Tests that ``STM32CubeProgrammerBinaryRunner`` class can be created using
the ``create`` factory method and that ``flash`` command works as expected.
"""
system.return_value = tc["system"]
args = ["--port", tc["port"]]
if tc["frequency"]:
args.extend(["--frequency", tc["frequency"]])
if tc["reset_mode"]:
args.extend(["--reset-mode", tc["reset_mode"]])
if tc["start_address"]:
args.extend(["--start-address", str(tc["start_address"])])
if tc["conn_modifiers"]:
args.extend(["--conn-modifiers", tc["conn_modifiers"]])
if tc["cli"]:
args.extend(["--cli", str(tc["cli"])])
if tc["use_elf"]:
args.extend(["--use-elf"])
if tc["erase"]:
args.append("--erase")
if tc["extload"]:
args.extend(["--extload", tc["extload"]])
if tc["tool_opt"]:
args.extend(["--tool-opt", " " + tc["tool_opt"][0]])
parser = argparse.ArgumentParser(allow_abbrev=False)
STM32CubeProgrammerBinaryRunner.add_parser(parser)
arg_namespace = parser.parse_args(args)
runner = STM32CubeProgrammerBinaryRunner.create(runner_config, arg_namespace)
runner.run("flash")
require.assert_called_with(tc["cli_path"])
assert check_call.call_args_list == [call(x) for x in tc["calls"]]