****************** BSP Structure ****************** General ======= Available platforms can be found on ``_. Two different workflows exist for the creation of a BSP: i) one for the Microcontroller Unit (MCU) platforms and ii) one for the Linux-based Platform. The BSP's structure for the two workflows are the same, although the internal mechanism differs. The following sections focuses on the *common* Linux-based workflow, while the last chapter of this guide explains how to create a BSP for an MCU platform and the points that a platform developper should take care of when creating a *more complex* MCU BSP. The structure of the repository is the following (see Figure 1): - **platforms:** This folder contains all the developer platforms’ sources repositories. The developer platform’s source repository is the base repository of a platform. It is accessed by the docker containers of the developer platform for several purposes. The developer platform’s source repository is provided to the user within the DPE, along with the docker images for the different steps of the workflows. - **builders:** This folder contain all the platforms’ builder repositories. The developer platform’s builder repository is used to generate a builder docker image with the right environment to cross-compile for a target platform. Builder containers are used within the DPE workflow to generate AI-Apps for the selected platform. - **support:** This folder contains all the platforms support repositories. The developer platform’s support repository is used to generate a support docker image that walks the user to set up an embedded platform. Support containers are used within the DPE workflow to setup the platform (Dependencies, SD card, etc...). - **manager:** This folder contains all the platforms manager repositories. The developer platform’s manager repository is used to generate a manager docker image that allow the user to interact with the embedded platform once set up. Manager containers are used within the DPE workflow to install, launch and stop the Ai-Apps on the platform and to recover platform information (CPU frequencies, running Ai-Apps, etc...) .. figure:: ../assets/BSP_struct.png :height: 300 px :align: center :alt: BSP Structure :figclass: align-center Figure 1 BSP Structure Platform sources ================ The basic structure of platform’s sources directory for a developer platform is the following : | Platform_name | ├── platform | │ ├── toolchain.cmake | │ ├── conf | │ │ ├── docker-images | │ │ ├── builder-images | │ │ ├── manager-images | │ │ └── support-images | │ └── assets | ├── sdk | │ └── platform.cmake | ├── package.yml | └── platform.yml The usage for each file/directory is the following: - **platform/toolchain.cmake:** This file is used to set platform’s toolchain information needed during the Cmake compilation. For example, this file sets the platform processor type, the different compilers included in the platform’s toolchain and the sysroot used by the platform for cross-compilation. This file is a key element, since it sets the necessary information for cross-compilation during the build process. - **platform/toolchain.cmake:** This file is used to set platform’s toolchain information needed during the Cmake compilation. For example, this file sets the platform processor type, the different compilers included in the platform’s toolchain and the sysroot used by the platform for cross-compilation. This file is a key element, since it sets the necessary information for cross-compilation during the build process. - **platform/assets:** This folder can contain all sort of files that need to be used during the build process. For example, it will contain the etcher tool used to flash the SD-card. It can also contain the image for the SD-card if the image does not have to be manually downloaded by the user - **sdk/platform.cmake:** This file is used to define and include the toolchain file as well as different options used during the build process, e.g., options such as the CBLAS library to use and the defaults LPDNN plugins. - **package.yml:** This file contains the name of the package that contain the Ai-Artifact (the platform in this case) and different metadata related to the Ai Artifact. For the full catalog of the different types and information that a package.yml file can contain, please check ``_ - **platform.yml:** This file contains the ID for the platform, as well as different metadata Platform support ================ The basic structure of the platform’s support directory for a developer platform is the following: | Platform_name | ├── build.sh | ├── conf | │ ├── packages-deb | │ └── packages-pip | ├── data | │ ├── deb | │ └── pip | ├── deps | │ ├── assets | │ ├── check_sha.sh | │ └── wizard.rst | ├── Dockerfile | ├── README.md | ├── scripts | │ ├── build.sh | │ ├── deps.sh | │ └── setup.sh | ├── setup | │ ├── assets | │ ├── setup_target.sh | │ └── wizard.rst | └── wizard_server The usage for each file/directory is the following: - **build.sh:** This file is used to build the docker image from the Dockerfile located in the root support platform directory. You can launch it locally from your host and it will generate a new image with the latest tag. - **conf/packages-deb:** This file lists the deb packages that are installed in the support docker image. If new packages are to be added, this list needs to be updated. - **conf/packages-pip:** This file lists the pip packages installed in the support docker image. If new packages are to be added, this list needs to be updated. - **data/deb:** This folder contains the deb packages, corresponding to those listed in conf/packages-deb, that will be installed when building the docker images. - **data/pip:** This folder contains the pip packages that will be installed when building the docker images. Those pip packages correspond to the content of conf/packages-pip file. - **deps:** The deps folder contains all the files used when the platform needs additional actions to setup the platform, for instance, (in the jetson_nano-jetpack4.4’s support, the OS image has to be downloaded manually by the user because of license restriction. This folder is optional if the platform doesn't need additional actions. - **deps/assets:** This folder contain all the images (jpeg/png) used in the dependencies’ wizard. See next points for wizard explanation. - **deps/check_sha.sh:** This file can be used to check the integrity of deps files after the download. See jetson_nano-jetpack4.4 support for an example. - **deps/wizard.rst:** This file is the wizard template used to download the platform dependencies. The wizard walks the user through the process to simplify the required actions. - **Dockerfile:** This Dockerfile is used for building the docker image for the support container. The Dockerfile performs several functions: - Must install the deb and pip files included in data/ - Copy the different scripts (one from manager docker for ssh and all the script in script folder) - Install the setup wizard - **README.md:** This file contains the name of the platform as title. More information about the specific implementation on the support docker for a platform can be referenced here. - **scripts/build.sh:** This script will be used during the setup of the platform inside the docker container. In most cases, it will decompress the OS image to burn the SD card using the etcher tool. It may rename the OS image too. - **scripts/build.sh:** This script will be used during the setup of the platform inside the docker container. In most cases, it will decompress the OS image to burn the SD card using the etcher tool. It may rename the OS image too. - **scripts/setup.sh:** This script will launch the setup wizard. - **setup/assets:** This folder contain all the images used in the support wizard. - **setup/setup_target.sh:** This script will generate the ssh credentials and install them on the target board with the information the user gives during the setup wizard for ssh connection. - **setup/wizard.rst:** This file is the wizard template used in the setup wizard. The wizard walks the user through the process to simplify the required actions. - **wizard_server:** This folder is a git submodule that is cloned in each support directory to enable the wizards on the host machine. Platform builder ================ The basic structure of platform builder directory for a developer platform is the following: | Platform_name | ├── build.sh | ├── conf | │  ├── packages-deb | │  └── packages-pip | ├── data | │  ├── deb | │ ├── pip | │  └── other | ├── Dockerfile | └── README.md The usage for each file/directory is the following: - **build.sh:** This file is used to build the docker image from the Dockerfile that is in the builder’s platform root directory. You can launch it locally from your host and it will generate a new image with the latest tag. - **conf/packages-deb:** This file lists all the deb packages installed in the builder docker. If new packages are to be added, this list needs to be updated. - **conf/packages-pip:** This file lists the pip packages installed in the builder docker. If new packages are to be added, this list needs to be updated. - **data/deb:** This folder contains the deb packages, corresponding to those in conf/packages-deb, that will be installed when building the docker images. - **data/pip:** This folder contains the pip packages that will be installed when building the docker images. Those pip packages should correspond to the content of conf/packages-pip file. - **data/other:** This folder contains tools used in the builder docker images. For example, for the stm32mp157a-dk1 platform, this folder contains the script setting up the toolchain in the docker container. - **Dockerfile:** This Dockerfile is used for building docker image for builder docker. The Dockerfile performs several actions: - Must add and install the different files in the data folder. - Must also create a user in the docker container that will be used to build the applications. This is where all the actions needed for cross-compilation will be done e.g., install toolchain, set path, etc... - **README.md:** This file contains the name of the platform as title. More information about the specific implementation on the builder docker for a platform can be referenced here. Platform manager ================ The basic structure of platform manager directory for a platform is the following: | Platform_name | ├── build.sh | ├── Dockerfile | ├── helpers | │  ├── config | │  │  ├── benchmark_mode.sh | │  │  └── frequency_governor.sh | │  └── system_stats.sh | └── README.md The usage for each file/directory is the following: - **build.sh:** This file is used to build the docker image from the Dockerfile that is in the manager platform’s root directory. You can launch it locally from your host and it will generate a new image with the latest tag. - **Dockerfile:** This Dockerfile is used for building docker image for manager docker. This Dockerfile is based on the ssh docker image and will just copy the helpers' files that are specific to the target platform in the docker image. - **helpers:** This folder contain all the scripts used to retrieve information about the system while running an AI App. - **README.md:** This file contains the name of the platform as title. More information about the specific implementation on the manager docker for a platform can be referenced here. ******************* How to create a BSP ******************* The first step that needs to be performed to create a BSP is to complete the four main directories explained in the previous section, namely, sources, support, builder and, manager, with all the needed dependencies, toolchains, OS images, etc. Once this step is performed and the repositories are push to the BonsApp’s gitlab account, the docker images will be built and stored in the BMP. Figure 2 depicts the flow chart to create a BSP for a target embedded platform. .. figure:: ../assets/BSP_Flow_Chart.png :height: 550 px :align: center :alt: BSP Structure :figclass: align-center Figure 2 BSP Flow Chart The previous step would make the platform ready to use within LPDNN, BonsAPPs inference framework. To date, LPDNN is not yet open publicly and only BonsAPPs developers have access to it. From the user’s perspective, or 3rd party developers, platforms are given in the shape of a BSP. Thus, in this section, we explain how to build a BSP. From a user’s perspective, the platform’s support sources package is the only one that is downloaded from the Bonseyes AI Marketplace to set up a target platform. It provides the following content: - Documentation for the platform. - Docker to set up the target hardware, management server and cross compilation environment. By building the platform’s support sources package it is possible to create a platform build that contains: - A builder docker image with the cross-compilation environment. - A manager docker image that is used to control a target hardware. - A support docker image with all support files required to setup the target hardware. How the platform works ====================== Platform build ******************* During the build process of the the platform's sources (``bonseyes platform build``) the following happens: 1. All docker images listed in ``platform/conf/docker-images`` are pulled 2. The following scripts are executed in the support docker (``platform/conf/support-image``): a. The script ``scripts/deps.sh`` to download all the dependencies that are not distributed in the support package to the directory ``${DEPS_DIR}``.If something cannot be downloaded automatically, the script can print instructions for the user on the standard output. b. The script ``scripts/build.sh`` is executed to create: - (optional) The sources of the builder docker in ``${BUILDER_SOURCES_DIR}`` - (optional) The manager docker docker in ``${MANAGER_SOURCES_DIR}`` - (optional) The target OS image in ``${OS_DIR}`` 3. The sources in ``${BUILDER_SOURCES_DIR}`` are built if a Dockerfile is detected. The image is named with the name listed in ``platform/conf/builder-image``. 4. The sources in ``${MANAGER_SOURCES_DIR}`` are built if a Dockerfile is detected. The image is named with the name listed in ``platform/conf/manager-image``. The directories ``${DEPS_DIR}``, ``${BUILDER_SOURCES_DIR}``, ``${MANAGER_SOURCES_DIR}`` and ``${OS_DIR}`` are sub-directories of the output directory of the ``bonseyes platform build`` command. Note: the option ``--force`` will force a full execution of the above steps even if some of the items were already present. This is useful in case someone wants to recreate some component that was changed. Beware, however, that step 1 will remove all the docker images listed and download them again. This means, for example, that if you have a local image for the support docker it will be overwritten. To avoid this the simplest way is to manually delete the output directory instead of using ``--force``. Remember that in order to have more debugging information when something is not working as expected you can set ``DEBUG=1`` in the command line, for example: .. code-block:: bash DEBUG=1 ai-app/bonseyes-cli/tool/bin/bonseyes --packages-dir platform/platforms platform build --platform-sources platform/platforms/jetson_xavier-jetpack4.4 ../sdk-build/platforms/jetson_xavier-jetpack4.4 Once this is done, the builder docker can be rebuilt by calling ``./build.sh`` in the same directory, if present or otherwise by running the bonseyes platform build command above This process relates to the following user documentation’s step: ``_ Target setup ************ During target setup (``bonseyes target setup``) the script ``setup.sh`` is executed in the support docker (``platform/conf/support-image``). The script has access to the output directory (``${TARGET_CONFIG_DIR}``) and the OS build (``${OS_DIR}``) directory created during the platform build. The script guides the user to setup the target and executes automatic setup when possible. If not possible, it prints instructions for the user on the standard output. This process relates to the following user documentation’s step: ``_ Manager server start: When starting a target manager server, the manager docker (``platform/conf/manager-image``) is started with the command line ``server --host 0.0.0.0 --port 5000``. The container must spawn an HTTP API server on the corresponding IP/port. The reference implementation of the server with the description of all APIs is described `here `_. Creating a package =================== To create a platform support source the first step is to create a new package that will contain it. You can follow the instruction : ``_ to do so. In the rest of this guide, we assume that the package has been created in the directory ``${PACKAGE_DIR}``. Platform metadata ================= The platform metadata file is typically stored in the file ``platform.yml`` and has the following minimal contents: .. code-block:: yaml metadata: title: Name of the platform description: | Multiline description of the platform platform_build: com_example/platforms/myplatform#build.yml The title and description entries describe the platform. The ``platform_build`` property defines the name of the platform build (consisting of a package name and a file path) that is created when one builds the sources. Documentation ============= The platform documentation should answer key questions posed by an end-user before starting to interact with the target platform. Thanks to the documentation, the user should be able to obtain all hardware and perform all administrative steps to be able to start working with it. Structure ********* The documentation has the following structure: - ``doc/hw``: documentation of the hardware - ``description.rst``: general description of the hardware - ``procurement.rst``: how to obtain the necessary hardware (board, cables, ...) - ``issues.rst``: known issue list of the target platform - ``assets``: support files (such as images) - ``demos/${NAME}/procurement.rst``: list of hardware that need to be acquired to run the specified type of demo - ``doc/sw``: documentation for OS, toolchain and deployment: - ``description.rst``: general description of the software environment - ``procurement.rst``: special instructions on how obtain the software (such as licenses that need to be acquired) - ``assets``: support files (such as images ) All documents are written in reStructuredText format, for a primer on this syntax see the `reStructuredText Primer `_.It is possible to include images by adding them in a subfolder asset in each folder. Use relative path to it. This choice allows to easily rendering the documentation in different formats (for the web, for print) and ensures a common and well-understood standard. Not all documents must include any heading as these are going to be automatically generated when the document is presented to the user. File details ************ doc/hw/description.rst ^^^^^^^^^^^^^^^^^^^^^^ This file should contain a description of the platform Key questions to be answered: - Do I know what industry this platform is targeting? - Do I know the target audience of the platform? - Do I know the features and benefits of the platform? - Do I know the target applications of the SoC? - Do I know the exact reference of SoC version and silicon revision? - Do I know what computing environment is offered by the SoC? - Do I have visual diagrams to assist in the review of the platform? - Do I know what sensors are supported on the platform? doc/hw/procurement.rst ^^^^^^^^^^^^^^^^^^^^^^ This document should contain a description of all required hardware necessary to start using the platform. Special hardware required only of some demos can be listed in the ``hw/demos/${NAME}/procurement.rst`` file. This document should contain: - Table of recommended hardware items, ID, photos, etc - Exact reference codes - is this a starter kit or individual items? - Where to order and approximate prices. Examples: - Essentials: Developer Starter Kit (Board, Power, Case, etc) - SD card - Micro-card reader for PC - Other materials: USB keyboard and mouse - Flash cables - HDMI display - HDMI cable Key questions to be answered: - Would I be able to provide my manager with an itemized order list and cost estimate? - Would I be able to provide my purchasing department with an itemized order list including part references to order the platform? - Do I know where to order? - Would I be able to start using the platform after I obtain all that is described? doc/hw/issues.rst ^^^^^^^^^^^^^^^^^ This file should list all know issues with the board. doc/sw/description.rst ^^^^^^^^^^^^^^^^^^^^^^ This document describes the software environment. Key questions to be answered: - Do I know what Operating System is? - Do I know what Deep Learning Frameworks are available? - Do I have visual diagrams to assist in the review of the platform software stack? - Do I know the Linux Board Support Package recommended for this platform including version of Linux OS and kernel? doc/sw/procurement.rst ^^^^^^^^^^^^^^^^^^^^^^ This document describes all software and licenses that need to be purchased to be able to use the platform. The objective of this document is to make sure that the developer can independently follow the dependencies download wizard without being blocked by other actors. The document should describe all contracts that need to be approved, all licenses that need to be acquired and other such activities that may require help from the purchasing or legal department. Examples: - Software that need to be bought - Licenses that need to be approved Key questions: - Do I know what software needs to be ordered or licensed to use the platform? - Would I be able to provide my purchasing department with an itemized order list including part references to order the software for the platform? - Do I know where to order? - Do I know all administrative tasks that need to be carried out to be able to use the platform software? Platform support files ====================== The platform support files are used during the build process of the platform’s sources package to generate builder docker, manager docker and system image that is used during target setup. The minimal list of files is the following: - ``platform/conf/docker-images``: The platform build process is designed to download all docker images at the start and work in off-line mode afterwards. This file lists the names of docker images (one per line) that are needed during the whole platform build process. This includes the name of the support docker and may include pre-built builder docker, pre-built manager docker or base images used to build them. - ``platform/conf/support-image``: Name of the image of the support docker used to build the platform sources - ``platform/conf/manager-image``: Name of the image of the manager docker used to control the target hardware. This can be either an image that is downloaded at the beginning of the build process (and in that case it must be included in ``platform/conf/docker-images``) or the name of the image that is build during the platform sources build process. - ``platform/conf/builder-image``: Name of the image of the builder docker used to cross-compile binaries for the target hardware. This can be either an image that is downloaded at the beginning of the build process (and in that case it must be included in ``platform/conf/docker-images``) or the name of the image that is build during the platform sources build process. - ``platform/toolchain.cmake``: `CMake toolchain file `_ that is used in the cross-compilation builder docker to compile binaries for the target. - ``platform/assets`` (optional): additional files that can be used during the platform sources build process. Support docker ============== The support docker must contain the following scripts: - ``deps.sh``: script to download the dependencies required for the platform - ``build.sh`` : script to create system image, builder and manager docker sources - ``setup.sh``: script to setup a target hardware These scripts are invoked by the ``bonseyes`` tool to build the platform and setup the target. The tool starts the script in the support docker, when creating the container, it mounts a number of host directories inside the docker and sets a number of environment variables to that are described below. deps.sh ******* The objective of the script is to save the dependencies in the directory specified by the ``$DEPS_DIR`` environment variable. The script can instruct the user to perform some manual actions such as downloading from a vendor website some files. To create an interactive experience the script can use the `wizard server `_. The script is invoked in a container that shares the network stack with the host (``--network host``). The script is invoked by the tooling with the following environment variables: - ``PLATFORM_DIR``: path of directory containing platform support files. - ``DEPS_DIR``: path of directory where the dependencies shall be stored - ``HOST_PLATFORM_DIR``: path of directory containing platform support files in the host file systems - ``HOST_DEPS_DIR``: path of directory where the dependencies will be stored in the host file systems build.sh ******** The objective of this script is to assemble the sources of the builder and manager docker in the directories specified by the environment variables ``BUILDER_SOURCES_DIR`` and ``MANAGER_SOURCES_DIR`` and to save in the directory specified in the environment variable ``OS_DIR`` the OS image for the target hardware. If the manager or the builder docker do not need to be built from sources (the pre-built image is specified in the ``platform/conf/docker-images`` file), then the script can leave the corresponding directory empty. If the target setup process does not require a system image the script can leave the ``OS_DIR`` empty. The script is invoked with no internet access; any data that need to be downloaded from internet must have been already downloaded by the ``deps.sh`` script. The script is invoked by the tooling with the following environment variables: - ``PLATFORM_DIR``: path of directory containing platform support files. - ``DEPS_DIR``: path of directory where the dependencies have been downloaded with the ``deps.sh`` script - ``OS_DIR``: path of directory where the OS image should be stored - ``BUILDER_SOURCES_DIR``: path of directory where the sources of the builder docker must be stored - ``MANAGER_SOURCES_DIR``: path of directory where the sources of the manager docker must be stored setup.sh ******** The objective of this script is to setup the target hardware and create a target configuration that will be used by the manager docker to establish a connection to the target hardware. The script must save the target configuration in the directory specified by the ``TARGET_CONFIG_DIR`` environment variable. The script may output instructions to the user on how to perform manual steps for the setup of the target hardware. To create an interactive experience the script can use the `wizard server `_. The script should not require internet access, any data that need to be downloaded from internet should have been already downloaded by the ``deps.sh`` script. The script is invoked in a container that shares the network stack with the host (``--network host``). The script is invoked by the tooling with the following environment variables: - ``PLATFORM_DIR``: path of directory containing platform support files. - ``DEPS_DIR``: path of directory where the dependencies have been downloaded with the ``deps.sh`` script - ``OS_DIR``: path of directory where the OS image built by the ``build.sh`` script is stored - ``HOST_PLATFORM_DIR``: path of directory containing platform support files in the host file systems - ``HOST_DEPS_DIR``: path of directory containing dependencies in the host file systems - ``HOST_OS_DIR``: path of directory containing the OS image in the host file systems Manager docker ============== The manager docker must contain an HTTP server that exposes an API to access the target hardware. The manager docker is executed with the following command line arguments: .. code-block:: bash server --host 0.0.0.0 --port 5000 The server must listen on the specified host and port. The bonseyes tooling is in charge of making this port available to the host. The reference implementation of the server with the description of all APIs is described `here `_. Builder docker ============== Supporting cross-compilation for several targets can be confusing and time-consuming since each target can require different tools, resources and toolchains that must all be installed and maintained by everybody that wants to work with that platform. To avoid this issue and ensure that everybody uses the same set of tools, each platform must provide a docker containing all and only the dependencies needed for the build. Creating a builder is not more difficult than creating a readme file with the list of dependencies, with the advantage that the build environment can be created automatically by docker, saving a lot of installation and maintenance effort. The builder docker image contains all that is needed to cross-compile build software for a target board. It is used to run the build process of benchmarks, LPDNN SDK and custom software. The image must provide the following: - C/C++ cross-compilation toolchain for the target - standard set of build support tool (such as cmake, make, …) - sysroot and header files for the libraries installed in the OS image ******* MCU BSP ******* The workflow for an MCU platform contains the same structure as the Linux-based platform but differs in many aspects: - In an MCU platform, there is no Operating System. When an application is built for the MCU platform, it will be directly flashed on the platform. This operation will be needed for each modification on the application. This point is important when the developer needs to create the Wizard that will help the user during the Build Platform and Target Setup parts. - The management of an MCU platform is different than the one used in Linux. MCUs do not have access to SSH, only to serial connection. Therefore, a command called "get-mcu-benchmark" has been added to the Bonseyes CLI to help in this regard. It is based on a Python script that needs to be modified during the creation of the manager docker to fetch the information from the board in JSON format. You can find an example of this script on the STM32H7 platform repository `here `__.The script already contains a structure with all the different fields printed as JSON. The important modification that have to be made when a new platform is added is the parsing of the data. The python script can be tested directly on the host machine without the manager docker during the development. - The cross-compilation system is based on Makefile. The builder will compile the code directly in the docker, using the make command. During the creation of the code that will be deployed on the board, manually or with an external tool (STM32CubeMX for example), make sure to warn the user that the code needs to be compiled with a Makefile.