From 36678fd420bcd527c7ff82020574dbf4489b044c Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Thu, 8 Apr 2021 22:46:02 +0000 Subject: [PATCH 1/6] =?UTF-8?q?[=C2=B5TVM]=20Zephyr:=20Allow=20user=20info?= =?UTF-8?q?rm=20if=20a=20board=20is=20emulated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some boards supported by Zephyr that run emulated by default, i.e. their .yaml config file sets the field "simulation: qemu", don't have the prefix "qemu_" on their names, so µTVM can't currently recognize it as an emulated target to properly use the QEMU transporter (instead of the serial port) to open a session against it. Such a boards usually have real physical (hardware) counterparts, being specific boards and not generic or "fake" ones simply tied to a CPU type of interest. That commit allows the µTVM user to explicitly inform that µTVM needs to use the QEMU transporter to open a session against a given board by adding the suffix "-qemu" to the board name. That is necessary because for boards that don't have the name prefixed by "qemu_" and even though run emulated by default on Zephyr there is no easy way to detect them, since it's not possible to determine it by looking at any Cmake generated file or by using the `west` command to query that info. The case where the board is emulated by default but has the prefix "qemu_" in its board name is already handled by the current code. Signed-off-by: Gustavo Romero --- python/tvm/micro/contrib/zephyr.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/python/tvm/micro/contrib/zephyr.py b/python/tvm/micro/contrib/zephyr.py index 3fc4d7897095..ed66ce1114fd 100644 --- a/python/tvm/micro/contrib/zephyr.py +++ b/python/tvm/micro/contrib/zephyr.py @@ -108,7 +108,18 @@ def __init__( f"project_dir supplied to ZephyrCompiler does not exist: {project_dir}" ) + if "qemu" in board: + self._qemu = True + + # For Zephyr boards that run emulated by default, i.e. "simulation: qemu" is set in + # the board's .yaml config file, and which their names don't have the prefix "qemu_", a + # suffix "-qemu" is used in microTVM to inform that the QEMU transporter has to be used. + # So the suffix needs to be trimmed off before the board name is passed to Zephyr. + 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 +268,14 @@ 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 = True if self._qemu else False ) @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 +327,7 @@ class ZephyrFlasher(tvm.micro.compiler.Flasher): def __init__( self, board, + qemu, zephyr_base=None, project_dir=None, subprocess_env=None, @@ -336,6 +348,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 +460,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( From eab2b60054cd2e8a79c8a094e45c0d7532306349 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Fri, 9 Apr 2021 00:01:07 +0000 Subject: [PATCH 2/6] =?UTF-8?q?[=C2=B5TVM]=20Add=20new=20target=20mps2=5Fa?= =?UTF-8?q?n521?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a new µTVM target to support the Arm reference board MPS2-AN521, which is based upon a Cortex-m33 core. For more details about that board, please see: http://developer.arm.com/tools-and-software/development-boards/fpga-prototyping-boards/mps2 Signed-off-by: Gustavo Romero --- python/tvm/target/target.py | 1 + 1 file changed, 1 insertion(+) 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"], } From 1dc05cd4c640c6e0bb569ceebaff2e20946defd8 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Fri, 9 Apr 2021 00:10:06 +0000 Subject: [PATCH 3/6] =?UTF-8?q?[=C2=B5TVM]=20Add=20an=20example=20for=20th?= =?UTF-8?q?e=20mps2=5Fan521=20board?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds an example on how to run the Zephyr demo under apps/ using as a target the Arm mps2_an521 board, which is emulated by default on Zephyr. The example is added to the tutorial script micro_tflite.py, where other examples for other targets exist. Signed-off-by: Gustavo Romero --- .../demo_runtime/boards/mps2_an521.conf | 28 +++++++++ .../demo_runtime/qemu-hack/qemu-system-arm | 1 + tests/lint/check_file_type.py | 2 + tutorials/micro/micro_tflite.py | 62 ++++++++++--------- 4 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 apps/microtvm/zephyr/demo_runtime/boards/mps2_an521.conf create mode 120000 apps/microtvm/zephyr/demo_runtime/qemu-hack/qemu-system-arm 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/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( From 5e6e5433edffcbc26855199ec36c8e54b30d0ab4 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Mon, 12 Apr 2021 15:23:12 +0000 Subject: [PATCH 4/6] Fix lint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix lint accordingly to the CI error. Please, discard this commit message when squashing it to commit: [µTVM] Zephyr: Allow user inform if a board is emulated in the series. Thanks, Gustavo --- python/tvm/micro/contrib/zephyr.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/python/tvm/micro/contrib/zephyr.py b/python/tvm/micro/contrib/zephyr.py index ed66ce1114fd..698dc3ba9673 100644 --- a/python/tvm/micro/contrib/zephyr.py +++ b/python/tvm/micro/contrib/zephyr.py @@ -268,14 +268,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 = True if self._qemu else False + immobile=True if self._qemu else False, ) @property def flasher_factory(self): return compiler.FlasherFactory( ZephyrFlasher, - (self._board, self._qemu,), + ( + self._board, + self._qemu, + ), dict( zephyr_base=self._zephyr_base, project_dir=self._project_dir, From fbe56a29fd9d15a52838057c6cd2c02fa8feed39 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Mon, 12 Apr 2021 15:41:32 +0000 Subject: [PATCH 5/6] Satisfy lint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Satisfy lint about boolean expression format. Please, discard this commit message when squashing it to commit: [µTVM] Zephyr: Allow user inform if a board is emulated in the series. Thanks, Gustavo --- python/tvm/micro/contrib/zephyr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/tvm/micro/contrib/zephyr.py b/python/tvm/micro/contrib/zephyr.py index 698dc3ba9673..3d4e517906a6 100644 --- a/python/tvm/micro/contrib/zephyr.py +++ b/python/tvm/micro/contrib/zephyr.py @@ -268,7 +268,7 @@ 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=True if self._qemu else False, + immobile=bool(self._qemu), ) @property From fecc59bcf1a566a1ecf1b5595af176f787faac94 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Mon, 12 Apr 2021 20:43:02 +0000 Subject: [PATCH 6/6] Address suggestion from Andrew MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address suggestion from Andrew in the review. Also updates the comment about suffix being trimmed off. Please discard that commit message when squashing into commit: [µTVM] Zephyr: Allow user inform if a board is emulated in the patch series. Thanks, Gustavo --- python/tvm/micro/contrib/zephyr.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/python/tvm/micro/contrib/zephyr.py b/python/tvm/micro/contrib/zephyr.py index 3d4e517906a6..ccaae6a984b3 100644 --- a/python/tvm/micro/contrib/zephyr.py +++ b/python/tvm/micro/contrib/zephyr.py @@ -108,15 +108,14 @@ def __init__( f"project_dir supplied to ZephyrCompiler does not exist: {project_dir}" ) - if "qemu" in board: - self._qemu = True - - # For Zephyr boards that run emulated by default, i.e. "simulation: qemu" is set in - # the board's .yaml config file, and which their names don't have the prefix "qemu_", a - # suffix "-qemu" is used in microTVM to inform that the QEMU transporter has to be used. - # So the suffix needs to be trimmed off before the board name is passed to Zephyr. - if "-qemu" in board: - board = board.replace("-qemu", "") + 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