aboutsummaryrefslogtreecommitdiff
path: root/targets
diff options
context:
space:
mode:
authorKristofer Jonsson <kristofer.jonsson@arm.com>2022-05-25 16:55:24 +0200
committerKristofer Jonsson <kristofer.jonsson@arm.com>2022-06-13 15:30:33 +0200
commit742261012c087285309bba34b081caf1c6c6ddab (patch)
treef69476623f504ef3d1e0a511ff5d92149d04e6be /targets
parent144b2d2d735d5b2e25894bdeacef7e03761025ad (diff)
downloadethos-u-core-platform-742261012c087285309bba34b081caf1c6c6ddab.tar.gz
Documenting porting guidelines
Change-Id: Icefe078200f9a6a497b410e6c713d80fb9db1ba0
Diffstat (limited to 'targets')
-rw-r--r--targets/demo/CMakeLists.txt143
-rw-r--r--targets/demo/retarget.c276
-rw-r--r--targets/demo/target.cpp135
3 files changed, 554 insertions, 0 deletions
diff --git a/targets/demo/CMakeLists.txt b/targets/demo/CMakeLists.txt
new file mode 100644
index 0000000..a1ba620
--- /dev/null
+++ b/targets/demo/CMakeLists.txt
@@ -0,0 +1,143 @@
+#
+# Copyright (c) 2022 Arm Limited.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed 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
+#
+# 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.
+#
+
+#############################################################################
+# Paths
+#############################################################################
+
+set(CORE_PLATFORM_PATH "${CMAKE_CURRENT_SOURCE_DIR}/<TODO>/core_platform" CACHE PATH "Path to Core Platform")
+
+#############################################################################
+# Default toolchain
+#############################################################################
+
+set(TARGET_CPU "<TODO e.g. cortex-m55>" CACHE STRING "Target CPU")
+
+if (NOT CMAKE_TOOLCHAIN_FILE)
+ # TODO Select default toolchain
+ # - Arm Clang: ${CORE_PLATFORM_PATH}/cmake/toolchain/armclang.cmake
+ # - GCC : ${CORE_PLATFORM_PATH}/cmake/toolchain/arm-none-eabi-gcc.cmake
+ # - Else : Implement your own toolchain file
+ set(CMAKE_TOOLCHAIN_FILE "${CORE_PLATFORM_PATH}/cmake/toolchain/armclang.cmake")
+endif()
+
+#############################################################################
+# Default configuration
+#############################################################################
+
+get_filename_component(ETHOSU_TARGET ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+message("Configuring target ${ETHOSU_TARGET}")
+
+set(ETHOSU_TARGET_NPU_CONFIG "<TODO> e.g. ethos-u65-256" CACHE STRING "NPU configuration")
+set(ETHOSU_TARGET_NPU_COUNT 1 CACHE INTERNAL "Number of NPUs")
+set(ETHOSU_TARGET_NPU_TA_COUNT 0 CACHE INTERNAL "Number of timing adapters per NPU")
+
+# Fast memory size
+# If the TFLM model and arena are placed in Flash/DRAM, and if the NPU is Ethos-U65,
+# then a smaller fast memory buffer can be placed in SRAM. This is called 'spilling'.
+set(FAST_MEMORY_SIZE 0 CACHE STRING "Size of relocated fast memory scratch tensor")
+set(MEMORY_MODEL "sram" CACHE STRING "Memory config for model")
+set(MEMORY_ARENA "sram" CACHE STRING "Memory config for arena")
+
+# UART settings
+set(UART0_BASE "<TODO>" CACHE INTERNAL "UART base address")
+set(UART0_BAUDRATE "<TODO e.g. 115200>" CACHE INTERNAL "UART baudrate, N/A for model and juno")
+set(SYSTEM_CORE_CLOCK "<TODO e.g. 25000000>" CACHE INTERNAL "System core clock (Hz)")
+
+#############################################################################
+# Project
+#############################################################################
+
+cmake_minimum_required(VERSION 3.21)
+
+project(ethos-u-demo VERSION 0.0.1)
+
+include(${CORE_PLATFORM_PATH}/cmake/helpers.cmake)
+
+#############################################################################
+# Target
+#############################################################################
+
+# Include common target
+add_subdirectory(${CORE_PLATFORM_PATH}/targets/common core_platform/target/common)
+
+# Include drivers
+add_subdirectory(../../drivers drivers)
+
+# Common defines
+target_compile_definitions(ethosu_target_common INTERFACE
+ # Configure NPU architecture and number of timing adapters
+ ETHOSU_NPU_COUNT=${ETHOSU_TARGET_NPU_COUNT}
+ ETHOSU_NPU_TA_COUNT=${ETHOSU_TARGET_NPU_TA_COUNT}
+
+ # Placement or TLFu model and area. 0 = SRAM, 1 = DRAM
+ # The scatter file and linker script must be designed to switch on these defines
+ ETHOSU_FAST_MEMORY_SIZE=${FAST_MEMORY_SIZE}
+ ETHOSU_MODEL=$<STREQUAL:${MEMORY_MODEL},dram>
+ ETHOSU_ARENA=$<STREQUAL:${MEMORY_ARENA},dram>)
+
+# Linker script
+set(LINK_FILE platform CACHE STRING "Link file")
+
+ethosu_target_link_options(ethosu_target_link INTERFACE
+ LINK_FILE ${LINK_FILE}
+ ENTRY Reset_Handler)
+
+target_sources(ethosu_target_startup INTERFACE
+ retarget.c
+ target.cpp)
+
+target_link_libraries(ethosu_target_startup INTERFACE
+ $<$<TARGET_EXISTS:ethosu_core_driver>:ethosu_core_driver>
+ # TODO customize which libraries to include
+ mpu
+ ethosu_mhu_dummy
+ ethosu_uart_cmsdk_apb)
+
+if (TARGET ethosu_core_driver)
+ target_compile_definitions(ethosu_core_driver PUBLIC
+ ETHOSU
+
+ # The TFLM arena is accessed over base address 1. The region config
+ # controls if the memory transactions are routed over AXI 0 (region config
+ # 0 or 1) or AXI 1 (region config 2 or 3).
+ NPU_REGIONCFG_1=$<if:$<STREQUAL:${MEMORY_ARENA},dram>,0,2>)
+endif()
+
+###############################################################################
+# CTest
+###############################################################################
+
+# TODO Uncomment to enable ctest
+# include(CTest)
+
+# Uncomment if Python interpreter is needed
+#set(Python3_FIND_STRATEGY LOCATION)
+#find_package(Python3 COMPONENTS Interpreter)
+
+# TODO Uncomment if ETHOSU_ARCH and ETHOSU_NUM_MACS are needed
+# ethosu_get_architecture(${ETHOSU_TARGET_NPU_CONFIG})
+
+set(ETHOSU_COMMAND_DEFAULT <TODO test command> CACHE INTERNAL "Default test command")
+
+###############################################################################
+# Applications
+###############################################################################
+
+add_subdirectory(${CORE_PLATFORM_PATH}/applications core_platform/applications)
+add_subdirectory(../../applications applications)
diff --git a/targets/demo/retarget.c b/targets/demo/retarget.c
new file mode 100644
index 0000000..3355e2e
--- /dev/null
+++ b/targets/demo/retarget.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2019-2022 Arm Limited.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed 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
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "uart_stdout.h"
+
+// armclang retargeting
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
+#include <rt_misc.h>
+#include <rt_sys.h>
+
+/* Standard IO device handles. */
+#define STDIN 0x8001
+#define STDOUT 0x8002
+#define STDERR 0x8003
+
+#define RETARGET(fun) _sys##fun
+#define IO_OUTPUT(len) 0
+
+#else
+/*
+ * This type is used by the _ I/O functions to denote an open
+ * file.
+ */
+typedef int FILEHANDLE;
+
+/*
+ * Open a file. May return -1 if the file failed to open.
+ */
+extern FILEHANDLE _open(const char * /*name*/, int /*openmode*/);
+
+/* Standard IO device handles. */
+#define STDIN 0x00
+#define STDOUT 0x01
+#define STDERR 0x02
+
+#define RETARGET(fun) fun
+#define IO_OUTPUT(len) len
+
+#endif
+
+/* Standard IO device name defines. */
+const char __stdin_name[] __attribute__((aligned(4))) = "STDIN";
+const char __stdout_name[] __attribute__((aligned(4))) = "STDOUT";
+const char __stderr_name[] __attribute__((aligned(4))) = "STDERR";
+
+void _ttywrch(int ch) {
+ (void)fputc(ch, stdout);
+}
+
+FILEHANDLE RETARGET(_open)(const char *name, int openmode) {
+ (void)openmode;
+
+ if (strcmp(name, __stdin_name) == 0) {
+ return (STDIN);
+ }
+
+ if (strcmp(name, __stdout_name) == 0) {
+ return (STDOUT);
+ }
+
+ if (strcmp(name, __stderr_name) == 0) {
+ return (STDERR);
+ }
+
+ return -1;
+}
+
+int RETARGET(_write)(FILEHANDLE fh, const unsigned char *buf, unsigned int len, int mode) {
+ (void)mode;
+
+ switch (fh) {
+ case STDOUT:
+ case STDERR: {
+ int c;
+ unsigned int i;
+
+ for (i = 0; i < len; i++) {
+ c = fputc(buf[i], stdout);
+ if (c == EOF) {
+ return EOF;
+ }
+ }
+
+ return IO_OUTPUT(len);
+ }
+ default:
+ return EOF;
+ }
+}
+
+int RETARGET(_read)(FILEHANDLE fh, unsigned char *buf, unsigned int len, int mode) {
+ (void)mode;
+
+ switch (fh) {
+ case STDIN: {
+ int c;
+ unsigned int i;
+
+ for (i = 0; i < len; i++) {
+ c = fgetc(stdin);
+ if (c == EOF) {
+ return EOF;
+ }
+
+ buf[i] = (unsigned char)c;
+ }
+
+ return IO_OUTPUT(len);
+ }
+ default:
+ return EOF;
+ }
+}
+
+int RETARGET(_istty)(FILEHANDLE fh) {
+ switch (fh) {
+ case STDIN:
+ case STDOUT:
+ case STDERR:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int RETARGET(_close)(FILEHANDLE fh) {
+ if (RETARGET(_istty(fh))) {
+ return 0;
+ }
+
+ return -1;
+}
+
+int RETARGET(_seek)(FILEHANDLE fh, long pos) {
+ (void)fh;
+ (void)pos;
+
+ return -1;
+}
+
+int RETARGET(_ensure)(FILEHANDLE fh) {
+ (void)fh;
+
+ return -1;
+}
+
+long RETARGET(_flen)(FILEHANDLE fh) {
+ if (RETARGET(_istty)(fh)) {
+ return 0;
+ }
+
+ return -1;
+}
+
+int RETARGET(_tmpnam)(char *name, int sig, unsigned maxlen) {
+ (void)name;
+ (void)sig;
+ (void)maxlen;
+
+ return 1;
+}
+
+char *RETARGET(_command_string)(char *cmd, int len) {
+ (void)len;
+
+ return cmd;
+}
+
+void RETARGET(_exit)(int return_code) {
+ char exit_code_buffer[64] = {0};
+ const char *p = exit_code_buffer;
+
+ /* Print out the exit code on the uart so any reader know how we exit. */
+ /* By appending 0x04, ASCII for end-of-transmission the FVP model exits,
+ * if the configuration parameter shutdown_on_eot on the uart is enabled.
+ * For some versions of FVP, the shutdown_on_eot is broken, but the same
+ * behaviour can be created by passing specifying a shutdown_tag= for the
+ * uart when starting the model so that is added last as well.
+ */
+
+ snprintf(exit_code_buffer,
+ sizeof(exit_code_buffer),
+ "Application exit code: %d.\n" // Let the readers know how we exit
+ "\04\n" // end-of-transmission
+ "EXITTHESIM\n", // shutdown_tag
+ return_code);
+
+ while (*p != '\0') {
+ UartPutc(*p++);
+ }
+
+ while (1) {}
+}
+
+int system(const char *cmd) {
+ (void)cmd;
+
+ return 0;
+}
+
+time_t time(time_t *timer) {
+ time_t current;
+
+ current = 0; // To Do !! No RTC implemented
+
+ if (timer != NULL) {
+ *timer = current;
+ }
+
+ return current;
+}
+
+void _clock_init(void) {
+#if 0
+ // Example implementation based on SysTick
+ // For instance, use a counting var in a SysTick interrupt handler
+ // for clock() to use
+ SysTick->LOAD = (uint32_t) ((SystemCoreClock/100)-1UL);
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
+ SysTick->VAL = 0UL;
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
+#endif
+}
+
+clock_t clock(void) {
+ return (clock_t)-1;
+}
+
+int remove(const char *arg) {
+ (void)arg;
+ return 0;
+}
+
+int rename(const char *oldn, const char *newn) {
+ (void)oldn;
+ (void)newn;
+ return 0;
+}
+
+int fputc(int ch, FILE *f) {
+ (void)(f);
+ return UartPutc(ch);
+}
+
+int fgetc(FILE *f) {
+ (void)f;
+ return UartPutc(UartGetc());
+}
+
+#ifndef ferror
+/* arm-none-eabi-gcc with newlib uses a define for ferror */
+int ferror(FILE *f) {
+ (void)f;
+ return EOF;
+}
+#endif
diff --git a/targets/demo/target.cpp b/targets/demo/target.cpp
new file mode 100644
index 0000000..6fac5b0
--- /dev/null
+++ b/targets/demo/target.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2022 Arm Limited.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed 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
+ *
+ * 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.
+ */
+
+/****************************************************************************
+ * Includes
+ ****************************************************************************/
+
+#include "target.hpp"
+
+#ifdef ETHOSU
+#include <ethosu_driver.h>
+#endif
+
+#include "mpu.hpp"
+#include "uart_stdout.h"
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+
+using namespace EthosU;
+
+/****************************************************************************
+ * Defines
+ ****************************************************************************/
+
+#ifdef ETHOSU
+#define ETHOSU_BASE_ADDRESS <TODO>
+#define ETHOSU_IRQ <TODO>
+#endif
+
+/****************************************************************************
+ * Variables
+ ****************************************************************************/
+
+#ifdef ETHOSU
+#if defined(ETHOSU_FAST_MEMORY_SIZE) && ETHOSU_FAST_MEMORY_SIZE > 0
+__attribute__((aligned(16), section(".bss.ethosu_scratch"))) uint8_t ethosu_scratch[ETHOSU_FAST_MEMORY_SIZE];
+#else
+#define ethosu_scratch 0
+#define ETHOSU_FAST_MEMORY_SIZE 0
+#endif
+
+struct ethosu_driver ethosu0_driver;
+#endif
+
+/****************************************************************************
+ * Cache maintenance
+ ****************************************************************************/
+
+#if defined(CPU_CACHE_ENABLE) && defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
+extern "C" {
+void ethosu_flush_dcache(uint32_t *p, size_t bytes) {
+ if (p)
+ SCB_CleanDCache_by_Addr(p, bytes);
+ else
+ SCB_CleanDCache();
+}
+
+void ethosu_invalidate_dcache(uint32_t *p, size_t bytes) {
+ if (p)
+ SCB_InvalidateDCache_by_Addr(p, bytes);
+ else
+ SCB_InvalidateDCache();
+}
+}
+#endif
+
+/****************************************************************************
+ * Init
+ ****************************************************************************/
+
+namespace {
+
+#ifdef ETHOSU
+void ethosuIrqHandler() {
+ ethosu_irq_handler(&ethosu0_driver);
+}
+#endif
+
+} // namespace
+
+namespace EthosU {
+
+void targetSetup() {
+ // Initialize UART driver
+ UartStdOutInit();
+
+#ifdef ETHOSU
+ // Initialize Ethos-U NPU driver
+ if (ethosu_init(&ethosu0_driver,
+ reinterpret_cast<void *>(ETHOSU_BASE_ADDRESS),
+ ethosu_scratch,
+ ETHOSU_FAST_MEMORY_SIZE,
+ 1,
+ 1)) {
+ printf("Failed to initialize NPU.\n");
+ return;
+ }
+
+ // Assumes SCB->VTOR point to RW memory
+ NVIC_SetVector(static_cast<IRQn_Type>(ETHOSU_IRQ), (uint32_t)&ethosuIrqHandler);
+ NVIC_EnableIRQ(static_cast<IRQn_Type>(ETHOSU_IRQ));
+#endif
+
+ // MPU setup
+ // TODO Add memory protection unit configuration
+ const std::vector<ARM_MPU_Region_t> mpuConfig = {};
+
+ // Setup MPU configuration
+ Mpu::loadAndEnableConfig(&mpuConfig[0], mpuConfig.size());
+
+#if defined(CPU_CACHE_ENABLE) && defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
+ SCB_EnableICache();
+ SCB_EnableDCache();
+#endif
+}
+
+} // namespace EthosU