diff --git a/apps/microtvm/zephyr/demo_runtime/boards/mps2_an521.conf b/apps/microtvm/zephyr/demo_runtime/boards/mps2_an521.conf new file mode 100644 index 000000000000..3916b17c49cf --- /dev/null +++ b/apps/microtvm/zephyr/demo_runtime/boards/mps2_an521.conf @@ -0,0 +1,28 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# This file is specific to the MPS2-AN512 board. + +# For intrinsics used by generated optimized operators. +CONFIG_CMSIS_DSP=y + +# For random number generation. +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y + +# For debugging. +CONFIG_LED=n diff --git a/apps/microtvm/zephyr/demo_runtime/qemu-hack/qemu-system-arm b/apps/microtvm/zephyr/demo_runtime/qemu-hack/qemu-system-arm new file mode 120000 index 000000000000..58fc8296c31f --- /dev/null +++ b/apps/microtvm/zephyr/demo_runtime/qemu-hack/qemu-system-arm @@ -0,0 +1 @@ +./qemu-system-i386 \ No newline at end of file diff --git a/python/tvm/micro/contrib/zephyr.py b/python/tvm/micro/contrib/zephyr.py index 3fc4d7897095..ccaae6a984b3 100644 --- a/python/tvm/micro/contrib/zephyr.py +++ b/python/tvm/micro/contrib/zephyr.py @@ -108,7 +108,17 @@ def __init__( f"project_dir supplied to ZephyrCompiler does not exist: {project_dir}" ) + self._qemu = "qemu" in board + + # For Zephyr boards that run emulated by default but don't have the prefix "qemu_" in their + # board names, a suffix "-qemu" is added by users of µTVM when specifying the board name to + # inform that the QEMU transporter must be used just like for the boards with the prefix. + # Zephyr does not recognize the suffix, so we trim it off before passing it. + if "-qemu" in board: + board = board.replace("-qemu", "") + self._board = board + if west_cmd is None: self._west_cmd = [sys.executable, "-mwest.app.main"] elif isinstance(west_cmd, str): @@ -257,14 +267,17 @@ def binary(self, output, objects, options=None, link_main=True, main_options=Non "cmake_cache": ["CMakeCache.txt"], "device_tree": [os.path.join("zephyr", "zephyr.dts")], }, - immobile="qemu" in self._board, + immobile=bool(self._qemu), ) @property def flasher_factory(self): return compiler.FlasherFactory( ZephyrFlasher, - (self._board,), + ( + self._board, + self._qemu, + ), dict( zephyr_base=self._zephyr_base, project_dir=self._project_dir, @@ -316,6 +329,7 @@ class ZephyrFlasher(tvm.micro.compiler.Flasher): def __init__( self, board, + qemu, zephyr_base=None, project_dir=None, subprocess_env=None, @@ -336,6 +350,7 @@ def __init__( sys.path.pop(0) self._board = board + self._qemu = qemu self._zephyr_base = zephyr_base self._project_dir = project_dir self._west_cmd = west_cmd @@ -447,10 +462,7 @@ def _zephyr_transport(self, micro_binary): ) def flash(self, micro_binary): - cmake_entries = read_cmake_cache( - micro_binary.abspath(micro_binary.labelled_files["cmake_cache"][0]) - ) - if "qemu" in cmake_entries["BOARD"]: + if self._qemu: return self._zephyr_transport(micro_binary) build_dir = os.path.dirname( diff --git a/python/tvm/target/target.py b/python/tvm/target/target.py index baf07602bde6..748b4e8910c1 100644 --- a/python/tvm/target/target.py +++ b/python/tvm/target/target.py @@ -278,6 +278,7 @@ def intel_graphics(model="unknown", options=None): "host": [], "stm32f746xx": ["-mcpu=cortex-m7", "-march=armv7e-m"], "nrf5340dk": ["-mcpu=cortex-m33"], + "mps2_an521": ["-mcpu=cortex-m33"], } diff --git a/tests/lint/check_file_type.py b/tests/lint/check_file_type.py index 649b18820062..967df8d2b7b4 100644 --- a/tests/lint/check_file_type.py +++ b/tests/lint/check_file_type.py @@ -137,7 +137,9 @@ "apps/microtvm/zephyr/demo_runtime/boards/nrf5340dk_nrf5340_cpuapp.conf", "apps/microtvm/zephyr/demo_runtime/boards/nucleo_f746zg.conf", "apps/microtvm/zephyr/demo_runtime/boards/stm32f746g_disco.conf", + "apps/microtvm/zephyr/demo_runtime/boards/mps2_an521.conf", "apps/microtvm/zephyr/demo_runtime/qemu-hack/qemu-system-i386", + "apps/microtvm/zephyr/demo_runtime/qemu-hack/qemu-system-arm", "apps/microtvm/zephyr/demo_runtime/qemu-hack/qemu-system-riscv32", "apps/microtvm/zephyr/demo_runtime/qemu-hack/qemu-system-riscv64", # microTVM Virtual Machines diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index 279756b9ca43..4169a56e6570 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -174,25 +174,33 @@ # Defining the target # ------------------- # -# Now we create a build config for relay. turning off two options -# and then calling relay.build which will result in a C source -# file. When running on a simulated target, choose "host" below: -# TARGET = tvm.target.target.micro("host") - -# %% -# Compiling for physical hardware -# When running on physical hardware, choose a target and a board that -# describe the hardware. The STM32F746 Nucleo target and board is chosen in -# this commented code. Another option would be to choose the same target but -# the STM32F746 Discovery board instead. The disco board has the same -# microcontroller as the Nucleo board but a couple of wirings and configs -# differ, so it's necessary to select the "stm32f746g_disco" board below. -# -# .. code-block:: python +# Now we create a build config for relay, turning off two options and then calling relay.build which +# will result in a C source file for the selected TARGET. When running on a simulated target of the +# same architecture as the host (where this Python script is executed) choose "host" below for the +# TARGET and a proper board/VM to run it (Zephyr will create the right QEMU VM based on BOARD. In +# the example below the x86 arch is selected and a x86 VM is picked up accordingly: # TARGET = tvm.target.target.micro("host") -# BOARD = "nucleo_f746zg" # or "stm32f746g_disco" BOARD = "qemu_x86" +# +# Compiling for physical hardware +# When running on physical hardware, choose a TARGET and a BOARD that describe the hardware. The +# STM32F746 Nucleo target and board is chosen in the example below. Another option would be to +# choose the STM32F746 Discovery board instead. Since that board has the same MCU as the Nucleo +# board but a couple of wirings and configs differ, it's necessary to select the "stm32f746g_disco" +# board to generated the right firmware image. +# +# TARGET = tvm.target.target.micro("stm32f746xx") +# BOARD = "nucleo_f746zg" # or "stm32f746g_disco#" +# +# For some boards, Zephyr runs them emulated by default, using QEMU. For example, below is the +# TARGET and BOARD used to build a microTVM firmware for the mps2-an521 board. Since that board +# runs emulated by default on Zephyr the suffix "-qemu" is added to the board name to inform +# microTVM that the QEMU transporter must be used to communicate with the board. If the board name +# already has the prefix "qemu_", like "qemu_x86", then it's not necessary to add that suffix. +# +# TARGET = tvm.target.target.micro("mps2_an521") +# BOARD = "mps2_an521-qemu" ###################################################################### # Now, compile the model for the target: @@ -203,9 +211,8 @@ graph, c_mod, c_params = relay.build(mod, target=TARGET, params=params) -# %% -# Compiling for a simulated device -# -------------------------------- +# Compiling for a host simulated device +# ------------------------------------- # # First, compile a static microTVM runtime for the targeted device. In this case, the host simulated # device is used. @@ -214,11 +221,10 @@ os.path.join(tvm.micro.get_standalone_crt_dir(), "template", "host") ) -# %% -# Compiling for physical hardware -# For physical hardware, comment out the previous section and use this compiler definition instead. -# -# .. code-block:: python +# Compiling for physical hardware (or an emulated board, like the mps_an521) +# -------------------------------------------------------------------------- +# For physical hardware, comment out the previous section selecting TARGET and BOARD and use this +# compiler definition instead of the one above. # # import subprocess # from tvm.micro.contrib import zephyr @@ -227,15 +233,15 @@ # project_dir = os.path.join(repo_root, "apps", "microtvm", "zephyr", "demo_runtime") # compiler = zephyr.ZephyrCompiler( # project_dir=project_dir, -# board=BOARD if "stm32f746" in str(TARGET) else "qemu_x86", +# board=BOARD, # zephyr_toolchain_variant="zephyr", # ) # # opts = tvm.micro.default_options(f"{project_dir}/crt") # -# enable printing memory usage statistics of the runtime image -# generated by Zephyr compiler for the physical hardware -# logging.basicConfig(level="INFO") +# +# # Enable printing memory usage statistics for the runtime image generated by Zephyr +# logging.basicConfig(level="INFO") workspace = tvm.micro.Workspace() micro_binary = tvm.micro.build_static_runtime(