From 742261012c087285309bba34b081caf1c6c6ddab Mon Sep 17 00:00:00 2001 From: Kristofer Jonsson Date: Wed, 25 May 2022 16:55:24 +0200 Subject: Documenting porting guidelines Change-Id: Icefe078200f9a6a497b410e6c713d80fb9db1ba0 --- PORTING.md | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 PORTING.md (limited to 'PORTING.md') diff --git a/PORTING.md b/PORTING.md new file mode 100644 index 0000000..560b4ae --- /dev/null +++ b/PORTING.md @@ -0,0 +1,201 @@ +# Porting target + +Core Platform provides examples how to build and run applications on a few +target platforms. This guide will demonstrate how to use CMake to extend the +Core Platform build system with applications, drivers and targets. + +The build system is based on the idea that the *target* includes applications +and drivers. Applications should be platform agnostic without knowledge about +the target they are executing on, which in theory should allow applications to +be compiled for a range of targets. Consequently when generating the build +files, the path to the target is passed to CMake. + +``` +$ cmake -B build targets/ +``` + +All targets should include [targets/common](targets/common/CMakeLists.txt). This +directory defines a hierarchy of interface libraries, which are needed by helper +functions and other CMake targets to configure the build system. + +![CMake common targets](docs/cmake_target_common.png "CMake common targets") + +For a demo project that extends Core Platform, the subdirectories will be +included like the figure below illustrates. + +![CMake components](docs/cmake_components.png "CMake components") + +A complete dependency tree can be generated with Graphviz. + +``` +$ cmake -B build --graphviz out.dot targets/ +$ dot -T png -o out.png out.dot +``` + +# Create skeleton + +Create a `demo` directory, or name the directory to whatever is preferred. This +will be the parent directory for the demo project. + +``` +$ mkdir demo +$ cd demo +``` + +Create subdirectories for `applications`, `drivers` and `targets`. + +``` +$ mkdir applications drivers targets +$ touch applications/CMakeLists.txt drivers/CMakeLists.txt +``` + +# demo/targets/\/ + +Copy [\/targets/demo](targets/demo) to ``. +directory. Rename the directory to whatever is preferred. + +``` +$ cp -r /targets/demo targets/ +$ mv targets/demo targets/ +``` + +## CMakeLists.txt + +Open [targets/\/CMakeLists.txt](targets/demo/CMakeLists.txt) and +customize the settings. The important sections have been marked with `TODO`. + +### Default toolchain + +Core Platform provides example toolchain files for Arm Clang and GCC. If a +custom toolchain is needed, then this can be placed under +`demo/cmake/toolchain/.cmake` and the CMake variable +`CMAKE_TOOLCHAIN_FILE` set to point at this file. + +### CTest + +If there exists an emulator for the target platform - for example Arm Virtual +Hardware or QEmu - then `include(CTest)` can be uncommented and +`ETHOSU_COMMAND_DEFAULT` configured accordingly. Each of the application elf +files will be passed to the test command. + +Generating the build system, building and testing can be executed like this. + +``` +$ cmake -B build targets/ +$ cmake --build build +$ ctest --test-dir build +``` + +### Memory configuration + +[README.md#Memory configurations](README.md#memory-configurations) describes the +memory configurations that can be considered when mapping the TFLM model, arena +and fast memory buffer. The scatter file and linker scripts decide where the +buffers are placed in memory, but can for flexibility be written to switch on +defines set by the build system. + +The provided [CMakeLists.txt](targets/demo/CMakeLists.txt) demonstrates how the +CMake variables `FAST_MEMORY_SIZE`, `MEMORY_MODEL` and `MEMORY_ARENA` can be +used to export defines from the build system to the source files. + +## target.cpp + +`targetSetup()` is invoked from [targets/common/src/init.cpp](init.cpp), after +the runtime library has been initialized, before the `main()` function is +invoked. The purpose of this function is to initialize drivers, for example the +Ethos-U driver or the memory protection unit (MPU). + +Open [targets/\/target.cpp](targets/demo/target.cpp) in an editor +and customize the file. + +## platform.scatter and platform.ld + +Depending on the compiler either a scatter file (Arm Clang) or a linker script +(GCC) is used to describe the memory layout of the target. Documentation how to +write scatter files and linker scripts goes beyond the scope of this tutorial, +but can be found online. The scatter files and linker scripts provided for +Corstone-300 and Corstone-310 may also be used as reference. + +A design decision that needs to be made is if a boot loader or scatter loading +shall be used. A boot loader copies one or multiple binaries into memory before +lifting the reset on the Cortex-M CPU. Scatter loading typically means that a +single firmware binary has been written in flash. The Cortex-M CPU boots from +flash and copies memory segments from the firmware binary to for example ITCM, +DTCM and SRAM. + +# demo/applications/ + +Copy the [hello world](applications/hello_world) application to `applications/`. +This application can be used as template to start with. + +``` +$ cp -r /applications/hello_world applications/ +$ mv applications/hello_world applications/demo_app +``` + +Open `applications/demo_app/CMakeLists.txt` and rename the application from +`hello_world` to `demo_app`. + +``` +ethosu_add_executable_test(demo_app PRIVATE + SOURCES main.cpp) +``` + +Edit `applications/CMakeLists.txt` and add the `demo_app` subdirectory. + +``` +add_subdirectory(demo_app) +``` + +# demo/drivers/ + +Create a directory structure for a demo driver. Good practice is to separate +header files with public APIs in a separate folder. + +``` +$ mkdir drivers/demo +$ cd drivers/demo + +$ mkdir include src +$ touch CMakeList.txt include/demo.hpp src/demo.cpp +``` + +Add the demo subdirectory to `drivers/CMakeLists.txt`. + +``` +add_subdirectory(demo) +``` + +Edit `drivers/demo/CMakeLists.txt` and define a static library. + +``` +add_library(demo STATIC) +target_include_directories(demo PUBLIC include) +target_sources(demo PRIVATE src/demo.cpp) +``` + +Edit `drivers/demo/include/demo.hpp` and place types and prototypes here. + +``` +void demo(); +``` + +Edit `drivers/demo/src/demo.cpp`. `printf()` is used for its smaller memory +footprint, but `iostream` would also work. + +``` +#include + +void demo() { + printf("Hello Demo\n"); +} +``` + +Edit `targets//CMakeLists.txt` and link the `demo` library. + +``` +target_link_libraries(ethosu_target_startup INTERFACE + demo) +``` + +Edit `targets//target.cpp` and call `demo()` from `targetSetup()`. -- cgit v1.2.1