diff --git a/boards/common/spsdk.board.cmake b/boards/common/spsdk.board.cmake new file mode 100644 index 0000000000000..46e73509b0037 --- /dev/null +++ b/boards/common/spsdk.board.cmake @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(spsdk) +board_finalize_runner_args(spsdk) diff --git a/boards/nxp/common/Kconfig b/boards/nxp/common/Kconfig new file mode 100644 index 0000000000000..913c875f9e0b1 --- /dev/null +++ b/boards/nxp/common/Kconfig @@ -0,0 +1,8 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NXP_SPSDK_IMAGE + bool "Generate bootable firmware image with SPSDK" + help + Generate bootable firmware image with NXP Secure + Provisioning SDK (SPSDK). diff --git a/boards/nxp/imx95_evk/CMakeLists.txt b/boards/nxp/imx95_evk/CMakeLists.txt index 19302b77d01a3..8c6c965ce0678 100644 --- a/boards/nxp/imx95_evk/CMakeLists.txt +++ b/boards/nxp/imx95_evk/CMakeLists.txt @@ -12,5 +12,118 @@ if (CONFIG_SOF AND CONFIG_BOARD_IMX95_EVK_MIMX9596_M7_DDR) ) endif() +if(CONFIG_BOARD_NXP_SPSDK_IMAGE OR (DEFINED ENV{USE_NXP_SPSDK_IMAGE} + AND "$ENV{USE_NXP_SPSDK_IMAGE}" STREQUAL "y")) + find_program(7Z_EXECUTABLE 7z REQUIRED) + set(FIRMWARE_RELEASE "imx95-19x19-lpddr5-evk-boot-firmware-0.1") + # Parse SPSDK version + execute_process( + COMMAND spsdk --version + OUTPUT_VARIABLE SPSDK_VERSION_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" SPSDK_VERSION "${SPSDK_VERSION_OUTPUT}") + message(STATUS "SPSDK version is ${SPSDK_VERSION}") + + if(CONFIG_BOARD_IMX95_EVK_MIMX9596_M7) + set(AHAB_CONFIG_FILE "imx95_evk_mimx9596_m7_ahab.yaml") + + file(WRITE ${CMAKE_BINARY_DIR}/zephyr/${AHAB_CONFIG_FILE} + " + family: mimx9596 + revision: a1 + target_memory: standard + output: ${CMAKE_BINARY_DIR}/zephyr/flash.bin + containers: + - binary_container: + path: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/mx95a0-ahab-container.img + - container: + srk_set: none + images: + - lpddr_imem: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/lpddr5_imem_v202311.bin + lpddr_imem_qb: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/lpddr5_imem_qb_v202311.bin + lpddr_dmem: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/lpddr5_dmem_v202311.bin + lpddr_dmem_qb: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/lpddr5_dmem_qb_v202311.bin + oei_ddr: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/oei-m33-ddr.bin + - oei_tcm: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/oei-m33-tcm.bin + - system_manager: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/m33_image-mx95alt.bin + - cortex_m7_app: ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin + - v2x_dummy: true + ") + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${7Z_EXECUTABLE} x ${ZEPHYR_HAL_NXP_MODULE_DIR}/zephyr/blobs/imx-boot-firmware/${FIRMWARE_RELEASE}.bin -o./imx-boot-firmware -aos -bso0 -bse1 + COMMAND ${7Z_EXECUTABLE} x imx-boot-firmware/${FIRMWARE_RELEASE} -aos -bso0 -bse1 + COMMAND nxpimage ahab export -c ${CMAKE_BINARY_DIR}/zephyr/${AHAB_CONFIG_FILE} + ) + elseif(CONFIG_SOC_MIMX9596_A55) + file(WRITE ${CMAKE_BINARY_DIR}/zephyr/imx95_evk_mimx9596_a55_ahab_primary.yaml + " + family: mimx9596 + revision: a1 + target_memory: standard + output: ${CMAKE_BINARY_DIR}/zephyr/primary_ahab.bin + containers: + - binary_container: + path: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/mx95a0-ahab-container.img + - container: + srk_set: none + images: + - lpddr_imem: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/lpddr5_imem_v202311.bin + lpddr_imem_qb: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/lpddr5_imem_qb_v202311.bin + lpddr_dmem: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/lpddr5_dmem_v202311.bin + lpddr_dmem_qb: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/lpddr5_dmem_qb_v202311.bin + oei_ddr: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/oei-m33-ddr.bin + - oei_tcm: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/oei-m33-tcm.bin + - system_manager: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/m33_image-mx95evk.bin + - spl: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/u-boot-spl.bin-imx95-19x19-lpddr5-evk-sd + - v2x_dummy: true + ") + file(WRITE ${CMAKE_BINARY_DIR}/zephyr/imx95_evk_mimx9596_a55_ahab_secondary.yaml + " + family: mimx9596 + revision: a1 + target_memory: standard + output: ${CMAKE_BINARY_DIR}/zephyr/secondary_ahab.bin + containers: + - container: + srk_set: none + images: + - atf: ${CMAKE_BINARY_DIR}/zephyr/${FIRMWARE_RELEASE}/bl31-imx95-zephyr.bin + - image_path: ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin + load_address: '${CONFIG_SRAM_BASE_ADDRESS}' + entry_point: '${CONFIG_SRAM_BASE_ADDRESS}' + image_type: executable + core_id: cortex-a55 + is_encrypted: false + ") + file(WRITE ${CMAKE_BINARY_DIR}/zephyr/imx95_evk_mimx9596_a55_ahab_flash_template.yaml + " + family: mimx9596 + revision: latest + memory_type: serial_downloader + primary_image_container_set: ${CMAKE_BINARY_DIR}/zephyr/imx95_evk_mimx9596_a55_ahab_primary.yaml + secondary_image_container_set: ${CMAKE_BINARY_DIR}/zephyr/imx95_evk_mimx9596_a55_ahab_secondary.yaml + ") + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${7Z_EXECUTABLE} x ${ZEPHYR_HAL_NXP_MODULE_DIR}/zephyr/blobs/imx-boot-firmware/${FIRMWARE_RELEASE}.bin -o./imx-boot-firmware -aos -bso0 -bse1 + COMMAND ${7Z_EXECUTABLE} x imx-boot-firmware/${FIRMWARE_RELEASE} -aos -bso0 -bse1 + ) + if(SPSDK_VERSION VERSION_GREATER_EQUAL "3.0.0") + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND nxpimage bootable-image export -c ${CMAKE_BINARY_DIR}/zephyr/imx95_evk_mimx9596_a55_ahab_flash_template.yaml -o flash.bin + ) + else() + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND nxpimage bootable-image merge -c ${CMAKE_BINARY_DIR}/zephyr/imx95_evk_mimx9596_a55_ahab_flash_template.yaml -o flash.bin + ) + endif() + else() + message(FATAL_ERROR "SPSDK Image not supported on the platform!") + endif() + zephyr_blobs_verify(FILES + ${ZEPHYR_HAL_NXP_MODULE_DIR}/zephyr/blobs/imx-boot-firmware/${FIRMWARE_RELEASE}.bin + REQUIRED) +endif() + zephyr_library() zephyr_library_sources(board.c) diff --git a/boards/nxp/imx95_evk/Kconfig b/boards/nxp/imx95_evk/Kconfig new file mode 100644 index 0000000000000..1fd7aaba5e1ca --- /dev/null +++ b/boards/nxp/imx95_evk/Kconfig @@ -0,0 +1,4 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +source "boards/nxp/common/Kconfig" diff --git a/boards/nxp/imx95_evk/board.cmake b/boards/nxp/imx95_evk/board.cmake index 57089c3f1b089..437654e1e1ad2 100644 --- a/boards/nxp/imx95_evk/board.cmake +++ b/boards/nxp/imx95_evk/board.cmake @@ -3,3 +3,19 @@ if (CONFIG_SOF AND CONFIG_BOARD_IMX95_EVK_MIMX9596_M7_DDR) board_set_rimage_target(imx95) endif() + +if(CONFIG_BOARD_NXP_SPSDK_IMAGE OR (DEFINED ENV{USE_NXP_SPSDK_IMAGE} + AND "$ENV{USE_NXP_SPSDK_IMAGE}" STREQUAL "y")) + board_set_flasher_ifnset(spsdk) + + board_runner_args(spsdk "--family=mimx9596") + board_runner_args(spsdk "--bootloader=${CMAKE_BINARY_DIR}/zephyr/imx95-19x19-lpddr5-evk-boot-firmware-0.1/imx-boot-imx95-19x19-lpddr5-evk-sd.bin-flash_all") + board_runner_args(spsdk "--flashbin=${CMAKE_BINARY_DIR}/zephyr/flash.bin") + if(CONFIG_CPU_CORTEX_A55) + board_runner_args(spsdk "--containers=two") + else() + board_runner_args(spsdk "--containers=one") + endif() + + include(${ZEPHYR_BASE}/boards/common/spsdk.board.cmake) +endif() diff --git a/boards/nxp/imx95_evk/doc/index.rst b/boards/nxp/imx95_evk/doc/index.rst index 75aba8fd01d0b..4b52b0563c8ec 100644 --- a/boards/nxp/imx95_evk/doc/index.rst +++ b/boards/nxp/imx95_evk/doc/index.rst @@ -115,88 +115,139 @@ Programming and Debugging (A55) .. zephyr:board-supported-runners:: -Use this configuration to run basic Zephyr applications and kernel tests, -for example, with the :zephyr:code-sample:`synchronization` sample: +There are multiple methods to program and run Zephyr on the A55 core: + +Option 1. Boot Zephyr by Using SPSDK Runner +=========================================== + +SPSDK runner leverages SPSDK tools (https://spsdk.readthedocs.io), it builds an +bootable flash image ``flash.bin`` which includes all necessary firmware components, +such as ELE+V2X firmware, System Manager, TCM OEI, TF-A images etc. Using west flash +command will download the boot image flash.bin to DDR memory, SD card or eMMC flash. +By using flash.bin, as no U-Boot image is available, so TF-A will boot up Zephyr on +the first Cortex-A55 Core directly. + +In order to use SPSDK runner, it requires fetching binary blobs, which can be achieved +by running the following command: + +.. code-block:: console -1. Build and run the Non-SMP application + west blobs fetch hal_nxp + +.. note:: + + It is recommended running the command above after :file:`west update`. + +SPSDK runner is enabled by configure item :kconfig:option:`CONFIG_BOARD_NXP_SPSDK_IMAGE`, currently +it is not enabled by default for i.MX95 EVK board, so use this configuration to enable +it, for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization :host-os: unix :board: imx95_evk/mimx9596/a55 :goals: build + :gen-args: -DCONFIG_BOARD_NXP_SPSDK_IMAGE=y -This will build an image (zephyr.bin) with the synchronization sample app. +If :kconfig:option:`CONFIG_BOARD_NXP_SPSDK_IMAGE` is available and enabled for the board variant, +``flash.bin`` will be built automatically. The programming could be through below commands. +Before that, switch SW7[1:4] should be configured to 0b1001 for usb download mode +to boot, and USB1 and DBG ports should be connected to PC. There are 4 serial ports +enumerated (115200 8n1), and we use the first for M7 and the fourth for M33 System Manager. +(The flasher is spsdk which already installed via scripts/requirements.txt. +On linux host, usb device permission should be configured per Installation Guide +of https://spsdk.readthedocs.io) -Copy the compiled ``zephyr.bin`` to the first FAT partition of the SD card and -plug the SD card into the board. Power it up and stop the u-boot execution at -prompt. +.. code-block:: none -Use U-Boot to load and kick zephyr.bin to Cortex-A55 Core1: + # load and run without programming. for next flashing, execute 'reset' in the + # fourth serail port + $ west flash -.. code-block:: console + # program to SD card, then set SW7[1:4]=0b1011 to reboot + $ west flash --bootdevice sd - fatload mmc 1:1 0xd0000000 zephyr.bin; dcache flush; icache flush; cpu 1 release 0xd0000000 + # program to emmc card, then set SW7[1:4]=0b1010 to reboot + $ west flash --bootdevice=emmc -Or use the following command to kick zephyr.bin to Cortex-A55 Core0: +Option 2. Boot Zephyr by Using U-Boot Command +============================================= -.. code-block:: console +U-Boot "go" command can be used to start Zephyr on A55 core0 and U-Boot "cpu" command +is used to load and kick Zephyr to the other A55 secondary Cores. Currently "cpu" command +is supported in : `Real-Time Edge U-Boot`_ (use the branch "uboot_vxxxx.xx-y.y.y, +xxxx.xx is uboot version and y.y.y is Real-Time Edge Software version, for example +"uboot_v2023.04-2.9.0" branch is U-Boot v2023.04 used in Real-Time Edge Software release +v2.9.0), and pre-build images and user guide can be found at `Real-Time Edge Software`_. - fatload mmc 1:1 0xd0000000 zephyr.bin; dcache flush; icache flush; go 0xd0000000 +.. _Real-Time Edge U-Boot: + https://github.com/nxp-real-time-edge-sw/real-time-edge-uboot +.. _Real-Time Edge Software: + https://www.nxp.com/rtedge +Step 1: Download Zephyr Image into DDR Memory +--------------------------------------------- -It will display the following console output: +Firstly need to download Zephyr binary image into DDR memory, it can use tftp: .. code-block:: console - *** Booting Zephyr OS build v3.6.0-4569-g483c01ca11a7 *** - thread_a: Hello World from cpu 0 on imx95_evk! - thread_b: Hello World from cpu 0 on imx95_evk! - thread_a: Hello World from cpu 0 on imx95_evk! - thread_b: Hello World from cpu 0 on imx95_evk! - thread_a: Hello World from cpu 0 on imx95_evk! + tftp 0xd0000000 zephyr.bin + +Or copy the Zephyr image ``zephyr.bin`` SD card and plug the card into the board, for example +if copy to the FAT partition of the SD card, use the following U-Boot command to load the image +into DDR memory (assuming the SD card is dev 1, fat partition ID is 1, they could be changed +based on actual setup): -2. Build and run the SMP application +.. code-block:: console + + fatload mmc 1:1 0xd0000000 zephyr.bin; + +Step 2: Boot Zephyr +------------------- + +Use this configuration to run basic Zephyr applications and kernel tests, +for example, with the :zephyr:code-sample:`synchronization` sample: .. zephyr-app-commands:: :zephyr-app: samples/synchronization :host-os: unix - :board: imx95_evk/mimx9596/a55/smp + :board: imx95_evk/mimx9596/a55 :goals: build This will build an image (zephyr.bin) with the synchronization sample app. -Copy the compiled ``zephyr.bin`` to the first FAT partition of the SD card and -plug the SD card into the board. Power it up and stop the u-boot execution at -prompt. - -Use the following command to kick zephyr.bin to Cortex-A55 Core0: +Then use the following command to boot Zephyr on the core0: .. code-block:: console - fatload mmc 1:1 0xd0000000 zephyr.bin; dcache flush; icache flush; go 0xd0000000 + dcache off; icache flush; go 0xd0000000; +Or use "cpu" command to boot from secondary Core, for example Core1: + +.. code-block:: console + + dcache flush; icache flush; cpu 1 release 0xd0000000 It will display the following console output: + .. code-block:: console - *** Booting Zephyr OS build v3.7.0-rc3-15-g2f0beaea144a *** - Secondary CPU core 1 (MPID:0x100) is up - Secondary CPU core 2 (MPID:0x200) is up - Secondary CPU core 3 (MPID:0x300) is up - Secondary CPU core 4 (MPID:0x400) is up - Secondary CPU core 5 (MPID:0x500) is up - thread_a: Hello World from cpu 0 on imx95_evk! - thread_b: Hello World from cpu 4 on imx95_evk! - thread_a: Hello World from cpu 0 on imx95_evk! - thread_b: Hello World from cpu 3 on imx95_evk! + *** Booting Zephyr OS build v3.6.0-4569-g483c01ca11a7 *** thread_a: Hello World from cpu 0 on imx95_evk! - thread_b: Hello World from cpu 1 on imx95_evk! + thread_b: Hello World from cpu 0 on imx95_evk! thread_a: Hello World from cpu 0 on imx95_evk! - thread_b: Hello World from cpu 5 on imx95_evk! + thread_b: Hello World from cpu 0 on imx95_evk! thread_a: Hello World from cpu 0 on imx95_evk! - thread_b: Hello World from cpu 2 on imx95_evk! + +Option 3. Boot Zephyr by Using Remoteproc under Linux +===================================================== + +When running Linux on the A55 core, it can use the remoteproc framework to load and boot Zephyr, +refer to Real-Time Edge user guide for more details. Pre-build images and user guide can be found +at `Real-Time Edge Software`_. + Programming and Debugging (M7) ****************************** @@ -213,13 +264,47 @@ To program M7, an i.MX container image ``flash.bin`` must be made, which contain multiple elements required, like ELE+V2X firmware, System Manager, TCM OEI, Cortex-M7 image and so on. -The steps making flash.bin and programming should refer to ``Getting Started with +SPSDK runner is used to build ``flash.bin``, and it requires fetching binary blobs, which +can be achieved by running the following command: + +.. code-block:: console + + west blobs fetch hal_nxp + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Two methods to build and program ``flash.bin``. + +1. If :kconfig:option:`CONFIG_BOARD_NXP_SPSDK_IMAGE` is not available for the board variant, +the steps making flash.bin and programming should refer to ``Getting Started with MCUXpresso SDK for IMX95LPD5EVK-19.pdf`` in i.MX95 `MCUX SDK release`_. Note that for the DDR variant, one should use the Makefile targets containing the ``ddr`` keyword. - See ``4.2 Run an example application``, just rename ``zephyr.bin`` to ``m7_image.bin`` to make flash.bin and program to SD/eMMC. +2. If :kconfig:option:`CONFIG_BOARD_NXP_SPSDK_IMAGE` is available and enabled for the board variant, +``flash.bin`` will be built automatically. The programming could be through below commands. +Before that, switch SW7[1:4] should be configured to 0b1001 for usb download mode +to boot, and USB1 and DBG ports should be connected to PC. There are 4 serial ports +enumerated (115200 8n1), and we use the first for M7 and the fourth for M33 System Manager. +(The flasher is spsdk which already installed via scripts/requirements.txt. +On linux host, usb device permission should be configured per Installation Guide +of https://spsdk.readthedocs.io) + +.. code-block:: none + + # load and run without programming. for next flashing, execute 'reset' in the + # fourth serail port + $ west flash + + # program to SD card, then set SW7[1:4]=0b1011 to reboot + $ west flash --bootdevice sd + + # program to emmc card, then set SW7[1:4]=0b1010 to reboot + $ west flash --bootdevice=emmc + Zephyr supports two M7-based i.MX95 boards: ``imx95_evk/mimx9596/m7`` and ``imx95_evk/mimx9596/m7/ddr``. The main difference between them is the memory used. ``imx95_evk/mimx9596/m7`` uses TCM (ITCM for code and, generally, read-only diff --git a/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.yaml b/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.yaml index a4597d08db33a..9e2fd40eec908 100644 --- a/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.yaml +++ b/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.yaml @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -16,4 +16,7 @@ supported: - counter - i2c - uart +testing: + binaries: + - flash.bin vendor: nxp diff --git a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.yaml b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.yaml index 2d4eade0557f8..c4541d42f45dc 100644 --- a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.yaml +++ b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.yaml @@ -20,4 +20,7 @@ supported: - spi - netif:eth - counter +testing: + binaries: + - flash.bin vendor: nxp diff --git a/scripts/requirements-extras.txt b/scripts/requirements-extras.txt index 78f1ad7dac8c4..772f59b0ddc43 100644 --- a/scripts/requirements-extras.txt +++ b/scripts/requirements-extras.txt @@ -15,6 +15,9 @@ junit2html # Script used to build firmware images for NXP LPC MCUs. lpc_checksum +# used by NXP platform to generate/flash firmware images +spsdk == 2.6.0 + # used by scripts/build/gen_cfb_font_header.py - helper script for user Pillow>=10.3.0 diff --git a/scripts/west_commands/runners/__init__.py b/scripts/west_commands/runners/__init__.py index 2cb6073f51a05..4c0d7c90ed85b 100644 --- a/scripts/west_commands/runners/__init__.py +++ b/scripts/west_commands/runners/__init__.py @@ -58,6 +58,7 @@ def _import_runner_module(runner_name): 'rfp', 'silabs_commander', 'spi_burn', + 'spsdk', 'stm32cubeprogrammer', 'stm32flash', 'sy1xx', diff --git a/scripts/west_commands/runners/spsdk.py b/scripts/west_commands/runners/spsdk.py new file mode 100644 index 0000000000000..53a5b3138397a --- /dev/null +++ b/scripts/west_commands/runners/spsdk.py @@ -0,0 +1,131 @@ +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +'''Runner for flashing with SPSDK.''' + +import logging +import os +import subprocess +from pathlib import Path + +from runners.core import RunnerCaps, ZephyrBinaryRunner + + +class SPSDKBinaryRunner(ZephyrBinaryRunner): + '''Runner front-end for SPSDK.''' + + def __init__( + self, + cfg, + dev_id, + bootdevice=None, + family=None, + bootloader=None, + flashbin=None, + containers=None, + commander=None, + ): + super().__init__(cfg) + self.dev_id = dev_id + self.file = cfg.file + self.file_type = cfg.file_type + self.hex_name = cfg.hex_file + self.bin_name = cfg.bin_file + self.elf_name = cfg.elf_file + + self.bootdevice = bootdevice + self.family = family + self.bootloader = bootloader + self.flashbin = flashbin + self.containers = containers + self.commander = commander + + @classmethod + def name(cls): + return 'spsdk' + + @classmethod + def capabilities(cls): + return RunnerCaps(commands={'flash'}, dev_id=True) + + @classmethod + def dev_id_help(cls) -> str: + return 'SPSDK serial number for the board.' + + @classmethod + def do_add_parser(cls, parser): + parser.add_argument('--bootdevice', default='spl', help='boot device') + parser.add_argument('--family', required=True, help='family') + parser.add_argument('--bootloader', required=True, help='bootloader') + parser.add_argument('--flashbin', required=True, help='nxp container image flash.bin') + parser.add_argument( + '--containers', required=True, help='container count in flash.bin: one or two' + ) + parser.add_argument( + '--commander', + default='nxpuuu', + help="SPSDK Commander, default is nxpuuu", + ) + + @classmethod + def do_create(cls, cfg, args): + return SPSDKBinaryRunner( + cfg, + bootdevice=args.bootdevice, + family=args.family, + bootloader=args.bootloader, + flashbin=args.flashbin, + containers=args.containers, + commander=args.commander, + dev_id=args.dev_id, + ) + + def do_run(self, command, **kwargs): + self.commander = os.fspath(Path(self.require(self.commander)).resolve()) + + if command == 'flash': + self.flash(**kwargs) + + def flash(self, **kwargs): + self.logger.info(f"Flashing file: {self.flashbin}") + + kwargs = {} + if not self.logger.isEnabledFor(logging.DEBUG): + kwargs['stdout'] = subprocess.DEVNULL + + if self.dev_id: + cmd_with_id = [self.commander] + [(f'-us={self.dev_id}' if self.dev_id else '')] + else: + cmd_with_id = [self.commander] + if self.bootdevice == 'spl': + if self.containers == 'one': + cmd = cmd_with_id + ['run'] + [f"SDPS[-t 10000]: boot -f {self.flashbin}"] + self.logger.info(f"Command: {cmd}") + self.check_call(cmd, **kwargs) + elif self.containers == 'two': + cmd = cmd_with_id + ['run'] + [f"SDPS[-t 10000]: boot -f {self.flashbin}"] + self.logger.info(f"Command: {cmd}") + self.check_call(cmd, **kwargs) + cmd = cmd_with_id + ['run'] + ["SDPV: delay 1000"] + self.logger.info(f"Command: {cmd}") + self.check_call(cmd, **kwargs) + cmd = cmd_with_id + ['run'] + [f"SDPV: write -f {self.flashbin} -skipspl"] + self.logger.info(f"Command: {cmd}") + self.check_call(cmd, **kwargs) + cmd = cmd_with_id + ['run'] + ["SDPV: jump"] + self.logger.info(f"Command: {cmd}") + self.check_call(cmd, **kwargs) + else: + raise ValueError(f"Invalid containers count: {self.containers}") + else: + cmd = ( + [self.commander] + + ['write'] + + ['-b', f'{self.bootdevice}'] + + ['-f', f'{self.family}'] + + [f'{self.bootloader}'] + + [f'{self.flashbin}'] + ) + self.logger.info(f"Command: {cmd}") + self.check_call(cmd, **kwargs) diff --git a/scripts/west_commands/tests/test_imports.py b/scripts/west_commands/tests/test_imports.py index 6def98afa04a9..3be15e8d7b920 100644 --- a/scripts/west_commands/tests/test_imports.py +++ b/scripts/west_commands/tests/test_imports.py @@ -49,6 +49,7 @@ def test_runner_imports(): 'rfp', 'silabs_commander', 'spi_burn', + 'spsdk', 'stm32cubeprogrammer', 'stm32flash', 'sy1xx', diff --git a/west.yml b/west.yml index ba840341307be..c0d1419e0038b 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 0575edec4c4d2a9c31e50974024e0ace9514f7a3 + revision: dcb80803ee9d528c600d012aa4ac6515bbd8fb3d path: modules/hal/nxp groups: - hal