Skip to content

Example for running IREE in a bare-metal Arm environment.

Notifications You must be signed in to change notification settings

simon-camp/iree-bare-metal-arm

 
 

Repository files navigation

IREE Bare-Metal Arm Sample

Build and Test

DISCLAIMER: This project is not intended for everyday use and made available without any support. However, we welcome any kind of feedback via the issue tracker or if appropriate via IREE's communication channels, e.g. via the Discord server.

This projects demonstrates how to build IREE with the Arm GNU Toolchain for bare-metal Arm targets using either the open-source firmware library libopencm3 or CMSIS.

Getting Started

Prerequisites

You need CMake and the Arm GNU Toolchain installed on your host machine. Further, a C/C++ compiler is required to build IREE for your host machine.

Clone and Build

Clone

git clone https://github.com/iml130/iree-bare-metal-arm.git
cd iree-bare-metal-arm
git submodule update --init
./build_tools/update_iree_submodules.sh

Note:
    The submodules used within IREE themself include submodules, so that we advice to avoid an recursive update.

Note:
    It may happen that IREE submodules need to be updated.
    Thus it might not be sufficient to only pull the latest main branch.
    You can (re)run build_tools/update_iree_submodules.sh to update IREE's submodules.

Host Build

You will need an installation of IREE on your host machine. We recommend to install a snapshot and, if using pip, to only build some additional tools from source. Another option is to build everything on your host machine.

Install a Snapshot

TL;DR:
    You can use build_tools/install_iree_host_tools.sh to install the host build. Make sure you active the virtual environment afterwards.

Fetch and unpack the iree-dist tarball

You can create the virtual environment and unpack the snapshot via the following commands:

python3 -m venv venv-iree
source venv-iree/bin/activate
pip3 install -r requirements.txt

mkdir build-iree-host-tools
wget -i iree-release-link.txt -O build-iree-host-tools/iree-dist-linux-x86_64.tar.xz
tar xvfJ iree-dist-linux-x86_64.tar.xz -C build-iree-host-tools
rm iree-dist-linux-x86_64.tar.xz
Alternative: Use pip and install additional tools from source

Note:
    The installation of iree-compiler via pip is only supported up to version '20230112.395'.     To install newer versions, follow the instructions for the iree-dist tarball.

The snapshot can be installed via the following commands:

python3 -m venv venv-iree
source venv-iree/bin/activate
pip3 install -r requirements.txt
pip3 install -r requirements-compiler.txt

For further information, see the TensorFlow Integration or TensorFlow Lite Integration guide. The next lines can be used to build the missing tools from the already cloned submodule:

mkdir build-iree-host-tools
mkdir -p build-iree-host-install/bin
cd build-iree-host-tools

cmake -GNinja \
      -DCMAKE_C_COMPILER=clang \
      -DCMAKE_CXX_COMPILER=clang++ \
      -DIREE_ERROR_ON_MISSING_SUBMODULES=OFF \
      -DIREE_ENABLE_THREADING=OFF \
      -DIREE_HAL_DRIVER_DEFAULTS=OFF \
      -DIREE_BUILD_COMPILER=OFF \
      -DIREE_BUILD_SAMPLES=OFF \
      -DIREE_BUILD_TESTS=OFF \
      -DCMAKE_INSTALL_PREFIX=../build-iree-host-install \
      ../third_party/iree/
cmake --build . --target generate_embed_data iree-flatcc-cli

cp build_tools/embed_data/generate_embed_data ../build-iree-host-install/bin
cp build_tools/third_party/flatcc/iree-flatcc-cli ../build-iree-host-install/bin/
cd ..
Alternative: Build IREE from Source

You need to close all of IREE's submodules to build the host tools yourself. Running build_tools/update_iree_submodules.sh is not sufficient. Update all submodules by running:

cd third_party/iree
git submodule update --init
cd ../../

The lines below can be used to build IREE from the already cloned submodule:

mkdir build-iree-host
cd build-iree-host

cmake -GNinja \
      -DCMAKE_C_COMPILER=clang \
      -DCMAKE_CXX_COMPILER=clang++ \
      -DIREE_HAL_DRIVER_DEFAULTS=OFF \
      -DIREE_HAL_DRIVER_LOCAL_SYNC=ON \
      -DIREE_TARGET_BACKEND_DEFAULTS=OFF \
      -DIREE_TARGET_BACKEND_LLVM_CPU=ON \
      -DIREE_TARGET_BACKEND_VMVX=ON \
      -DIREE_BUILD_SAMPLES=OFF \
      -DIREE_BUILD_TESTS=OFF \
      -DCMAKE_INSTALL_PREFIX=../build-iree-host-install \
      ../third_party/iree/
cmake --build . --target install
cd ..

For further information, see the Getting started guide.

Target Support

The samples can be build for several STM32 32-bit Arm Cortex MCUs, for the Nordic nRF52840 SoC and for the Arm Corstone-300.

STM32 Targets

At the moment, the samples can be build for the following STM32 32-bit Arm Cortex MCUs:

  • STM32F407
  • STM32F411xE
  • STM32F446
  • STM32F746
  • STM32L476
  • STM32L4R5

Best support is provided for boards with the STM32F411RE or STM32F446 MCU. The samples are tested regularly on the STM32 Nucleo Boards NUCLEO-F411RE and NUCLEO-F446RE, whereas other boards or rather boards with other MCUs are only supported to a limited extend.

When building for an STM32F4 MCU, one can choose to either build the samples with libopencm3 or with CMSIS by either setting BUILD_WITH_LIBOPENCM3 or BUILD_WITH_CMSIS to ON. Depending on whether you build with libopencm3 or CMSIS, you need to pass the correct linker flags via CUSTOM_ARM_LINKER_FLAGS and need to specify the appropriate linker script via PATH_TO_LINKER_SCRIPT.

When using CMSIS and building for STM32411xE or STM32F446, one can select which UART to use. UART1 and UART2 can be initialized by setting USE_UART1 and USE_UART2 to ON. For STM32F407, STM32F746 and STM32L4R5 only UART2 is supported.

When using CMSIS and building for one of the supported STM32F4 MCUs, the clock can be configured in four ways. The internal clock HSI or the external clock HSE can either be used with or without using a phase-locked loop (PLL). To configure the clock set CLOCK_SOURCE to HSI, HSE, PLL_HSI or PLL_HSE. The option defaults to HSI.

When using CMSIS and building for STM32L476 or the STM32L4R5, the clock can be configured in two ways. The internal clock HSI can either be used with or without using a phase-locked loop (PLL). To configure the clock set CLOCK_SOURCE to HSI or PLL_HSI. The option defaults to HSI. The options HSE and PLL_HSE are not supported on the STM32L476 since the NUCLEO-L476RG board does not allow to use the clock of the attached ST-LINK as the external clock by default. The STM32L476 and STM32L4R5 also have other clocks which are not supported.

When using an STM32L4R5 board, unusual behaviour might be encountered where the board locks up when resetting immediately after flashing some samples. This relates to the boards default boot configuration and can be fixed by setting the boot bits nBOOT0 to 1 and nSWBOOT to 0 once to select the main flash memory as the boot area. This is best done using the STM32CubeProgrammer.

Nordic Targets

At the moment, the only supported Nordic target is the nRF52840 DK board with a nRF52840. This target is only supported with CMSIS. The only supported UART is UART0 which can be initialized by setting USE_UART0 to ON.

Corstone-300 Target

The Corstone-300 target is only supported with CMSIS.

Target Build

To build for the desired target specify the ARM_TARGET (as listed above) and set ARM_CPU accordingly. The toolchain file supports building for the CPUs cortex-m4, cortex-m7 (defaults to the DP FPU) and cortex-m55.

mkdir build
cd build

# Set the path to the GNU Arm Embedded Toolchain, e.g.
# export PATH_TO_ARM_TOOLCHAIN="/usr/local/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi"

# To build with CMSIS
# export CUSTOM_ARM_LINKER_FLAGS=""
# export PATH_TO_LINKER_SCRIPT="`realpath ../build_tools/stm32f407xg-cmsis.ld`"

# To build with libopencm3
# export CUSTOM_ARM_LINKER_FLAGS="-nostartfiles"
# export PATH_TO_LINKER_SCRIPT="`realpath ../third_party/libopencm3-custom/stm32f407xg.ld`"


# export PATH_TO_IREE_HOST_BIN_DIR="`realpath ../build-iree-host-install/bin`"

cmake -GNinja \
#     -DBUILD_WITH_CMSIS=ON \
#     -DBUILD_WITH_LIBOPENCM3=ON \
      -DCMAKE_TOOLCHAIN_FILE="`realpath ../build_tools/cmake/arm-none-eabi-gcc.cmake`" \
      -DARM_TOOLCHAIN_ROOT="${PATH_TO_ARM_TOOLCHAIN}" \
      -DARM_CPU="cortex-m4" \
      -DARM_TARGET="STM32F407" \
      -DIREE_ERROR_ON_MISSING_SUBMODULES=OFF \
      -DIREE_HAL_DRIVER_LOCAL_SYNC=ON \
      -DIREE_HAL_EXECUTABLE_LOADER_EMBEDDED_ELF=ON \
      -DIREE_HAL_EXECUTABLE_LOADER_VMVX_MODULE=ON \
      -DIREE_HOST_BIN_DIR="${PATH_TO_IREE_HOST_BIN_DIR}" \
      -DCUSTOM_ARM_LINKER_FLAGS="${CUSTOM_ARM_LINKER_FLAGS}" \
      -DLINKER_SCRIPT="${PATH_TO_LINKER_SCRIPT}" \
#     -DUSE_UART1=ON \
#     -DUSE_UART2=ON \
      ..
cmake --build . --target sample_vmvx_sync

Note:
    You can use the build_tools/configure_build.sh shell script to configure the build.

Test with Renode

You can use Renode to execute the created binary.

wget https://github.com/renode/renode/releases/download/v1.13.3/renode-1.13.3.linux-portable.tar.gz
tar -xvzf renode-1.13.3.linux-portable.tar.gz

Execution is done via the interactive Renode shell (for headless execution see here):

cd renode_1.13.3_portable
./renode

Inside the shell you need to execute the following statements:

(monitor) include @${PATH_TO_REPOSITORY_ROOT}/third_party/renode/stm32f407.resc
(STM32F407) sysbus LoadELF @${PATH_TO_BINARY}
(STM32F407) start

You should be able to see the output of the executable in the analyzer window for uart2.

This example also comes with a robot test file:

cd renode_1.13.3_portable
./renode-test --variable BASE_DIR:${PATH_TO_REPOSITORY_ROOT} ${PATH_TO_REPOSITORY_ROOT}/tests/vmvx_sample.robot

Test with a Fixed Virtual Platform

The samples build for Corstone-300 can also be tested with an Arm Ecosystem Fixed Virtual Platform (FVP). The Corstone-300 Ecosysten FVP can be downloaded from the Arm Ecosystem FVP download page.

About

Example for running IREE in a bare-metal Arm environment.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 33.4%
  • CMake 29.6%
  • RobotFramework 18.9%
  • Shell 15.6%
  • Python 2.5%