MLBEDSW-2593 Build FreeRTOS kernel as a part of ethosu_core target

The ethosu_core target now includes the FreeRTOS kernel if the
CORE_SOFTWARE_RTOS is set to FreeRTOS. Currently supported
builds are for cortex M3, M4, M7, M33, and M55. The FreeRTOSConfig.h
file is generated as a part of the build.

Change-Id: Ief6921fd0d9aa3849497ef0810d2714a12eb6773
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 99d829c..564d4d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,6 +36,7 @@
 
 # Define build options
 set(CORE_SOFTWARE_RTOS "None" CACHE STRING "Select RTOS to include. (None, MbedOS, FreeRTOS, Zephyr)")
+string(TOLOWER ${CORE_SOFTWARE_RTOS} CORE_SOFTWARE_RTOS_LOWER)
 
 #
 # Build
@@ -55,6 +56,10 @@
 # Build Tensorflow library
 include(tensorflow.cmake)
 
+# Build RTOS
+add_subdirectory(rtos)
+target_link_libraries(ethosu_core INTERFACE ethosu_core_rtos)
+
 # Build applications
 add_subdirectory(applications)
 
diff --git a/rtos/CMakeLists.txt b/rtos/CMakeLists.txt
new file mode 100644
index 0000000..7c15d9e
--- /dev/null
+++ b/rtos/CMakeLists.txt
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+#
+# 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.
+#
+
+add_library(ethosu_core_rtos INTERFACE)
+
+# Include FreeRTOS kernel & link with ethosu_rtos target
+if(CORE_SOFTWARE_RTOS_LOWER STREQUAL "freertos")
+    set(FREERTOS_KERNEL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/freertos/freertos_kernel" CACHE PATH "Path to FreeRTOS kernel.")
+    add_subdirectory(freertos_config)
+    target_link_libraries(ethosu_core_rtos INTERFACE freertos_kernel)
+endif()
diff --git a/rtos/freertos_config/CMakeLists.txt b/rtos/freertos_config/CMakeLists.txt
new file mode 100644
index 0000000..bd3fd3c
--- /dev/null
+++ b/rtos/freertos_config/CMakeLists.txt
@@ -0,0 +1,104 @@
+#
+# Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+#
+# 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.
+#
+
+if(CMAKE_SYSTEM_PROCESSOR STREQUAL "cortex-m3")
+    add_compile_definitions(CPU_CORTEX_M3)
+elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "cortex-m33")
+    add_compile_definitions(CPU_CORTEX_M33)
+elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "cortex-m4")
+    add_compile_definitions(CPU_CORTEX_M4)
+elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "cortex-m55")
+    add_compile_definitions(CPU_CORTEX_M55)
+elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "cortex-m7")
+    add_compile_definitions(CPU_CORTEX_M7)
+else()
+    message(FATAL_ERROR "Unsupported compiler ${CMAKE_SYSTEM_PROCESSOR}.")
+endif()
+
+if((${TARGET} STREQUAL "mps2") OR (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m55"))
+    set("SYSTEM_CORE_CLOCK" "25000000")
+else()
+    set("SYSTEM_CORE_CLOCK" "32000000")
+endif()
+
+
+configure_file(FreeRTOSConfig.h.in FreeRTOSConfig.h)
+set(FREERTOS_CONFIG_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+# FreeRTOS kernel library
+add_library(freertos_kernel STATIC)
+
+# Set include directories
+target_include_directories(freertos_kernel PUBLIC
+    ${FREERTOS_KERNEL_PATH}/include
+    ${FREERTOS_CONFIG_INCLUDE_DIR}
+)
+
+# Add kernel source files
+target_sources(freertos_kernel PRIVATE
+    ${FREERTOS_KERNEL_PATH}/tasks.c
+    ${FREERTOS_KERNEL_PATH}/list.c
+    ${FREERTOS_KERNEL_PATH}/queue.c
+)
+
+# Add the heap implementation
+# heap_3 uses the compiler supplied malloc & free for the heap.
+target_sources(freertos_kernel PRIVATE
+    ${FREERTOS_KERNEL_PATH}/portable/MemMang/heap_3.c)
+
+if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m3")
+target_sources(freertos_kernel PRIVATE
+    ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM3/port.c
+)
+target_include_directories(freertos_kernel PUBLIC
+    ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM3
+)
+elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m4")
+    target_sources(freertos_kernel PRIVATE
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM4F/port.c
+    )
+    target_include_directories(freertos_kernel PUBLIC
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM4F
+    )
+elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m7")
+    target_sources(freertos_kernel PRIVATE
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM7/r0p1/port.c
+    )
+    target_include_directories(freertos_kernel PUBLIC
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM7/r0p1
+    )
+elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m33")
+    target_sources(freertos_kernel PRIVATE
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c
+    )
+    target_include_directories(freertos_kernel PUBLIC
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM33_NTZ/non_secure
+    )
+elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m55")
+# TODO: using the same port files as Cortex-M33. Update for Cortex-M55.
+    target_sources(freertos_kernel PRIVATE
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c
+    )
+    target_include_directories(freertos_kernel PUBLIC
+        ${FREERTOS_KERNEL_PATH}/portable/GCC/ARM_CM33_NTZ/non_secure
+    )
+else()
+    message(FATAL_ERROR "Invalid processor ${CMAKE_SYSTEM_PROCESSOR} when building FreeRTOS kernel")
+endif()
diff --git a/rtos/freertos_config/FreeRTOSConfig.h.in b/rtos/freertos_config/FreeRTOSConfig.h.in
new file mode 100644
index 0000000..58e13a7
--- /dev/null
+++ b/rtos/freertos_config/FreeRTOSConfig.h.in
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ *
+ * 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.
+ */
+/* Please refer to http://www.freertos.org/a00110.html for refernce. */
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+/******************************************************************************
+ * Defines
+ ******************************************************************************/
+/* Hardware features */
+#define configENABLE_MPU                                0
+#define configENABLE_FPU                                0
+#define configENABLE_TRUSTZONE                          0
+/* Scheduling */
+#define configCPU_CLOCK_HZ                              @SYSTEM_CORE_CLOCK@
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION         0
+#define configUSE_PREEMPTION                            1
+#define configUSE_TIME_SLICING                          1
+#define configMAX_PRIORITIES                            5
+#define configIDLE_SHOULD_YIELD                         1
+#define configUSE_16_BIT_TICKS                          0
+#define configRUN_FREERTOS_SECURE_ONLY                  1
+/* Stack and heap */
+#define configMINIMAL_STACK_SIZE                        (uint16_t)128
+#define configMINIMAL_SECURE_STACK_SIZE                 1024
+#define configTOTAL_HEAP_SIZE                           (size_t)(50 * 1024)
+#define configMAX_TASK_NAME_LEN                         12
+/* OS features */
+#define configUSE_MUTEXES                               1
+#define configUSE_TICKLESS_IDLE                         1
+#define configUSE_APPLICATION_TASK_TAG                  0
+#define configUSE_NEWLIB_REENTRANT                      0
+#define configUSE_CO_ROUTINES                           0
+#define configUSE_COUNTING_SEMAPHORES                   1
+#define configUSE_RECURSIVE_MUTEXES                     1
+#define configUSE_QUEUE_SETS                            0
+#define configUSE_TASK_NOTIFICATIONS                    1
+#define configUSE_TRACE_FACILITY                        1
+/* Hooks */
+#define configUSE_IDLE_HOOK                             0
+#define configUSE_TICK_HOOK                             0
+#define configUSE_MALLOC_FAILED_HOOK                    0
+/* Debug features */
+#define configCHECK_FOR_STACK_OVERFLOW                  0
+#define configASSERT(x)                                 if ((x) == 0) { taskDISABLE_INTERRUPTS(); for( ;; ); }
+#define configQUEUE_REGISTRY_SIZE                       0
+/* Timers and queues */
+#define configUSE_TIMERS                                0
+#define configTIMER_TASK_PRIORITY                       3
+#define configTIMER_TASK_STACK_DEPTH                    configMINIMAL_STACK_SIZE
+#define configTIMER_QUEUE_LENGTH                        5
+/* Task settings */
+#define INCLUDE_vTaskPrioritySet                        1
+#define INCLUDE_uxTaskPriorityGet                       1
+#define INCLUDE_vTaskDelete                             1
+#define INCLUDE_vTaskCleanUpResources                   0
+#define INCLUDE_vTaskSuspend                            1
+#define INCLUDE_vTaskDelayUntil                         1
+#define INCLUDE_vTaskDelay                              1
+#define INCLUDE_uxTaskGetStackHighWaterMark             0
+#define INCLUDE_xTaskGetIdleTaskHandle                  0
+#define INCLUDE_eTaskGetState                           1
+#define INCLUDE_xTaskResumeFromISR                      0
+#define INCLUDE_xTaskGetCurrentTaskHandle               1
+#define INCLUDE_xTaskGetSchedulerState                  0
+#define INCLUDE_xSemaphoreGetMutexHolder                0
+#define INCLUDE_xTimerPendFunctionCall                  1
+#define configUSE_STATS_FORMATTING_FUNCTIONS            1
+#define configCOMMAND_INT_MAX_OUTPUT_SIZE               2048
+#ifdef __NVIC_PRIO_BITS
+#define configPRIO_BITS                                 __NVIC_PRIO_BITS
+#else
+#define configPRIO_BITS                                 3
+#endif
+/* Interrupt settings */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         0x07
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5
+#define configKERNEL_INTERRUPT_PRIORITY                 (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY            (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
+#ifndef __IASMARM__
+    #define configGENERATE_RUN_TIME_STATS               0
+    #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
+    #define portGET_RUN_TIME_COUNTER_VALUE()            0
+    #define configTICK_RATE_HZ                          (TickType_t)10000
+#endif /* __IASMARM__ */
+#if defined(CPU_CORTEX_M3) || defined(CPU_CORTEX_M4) || defined(CPU_CORTEX_M7)
+#define xPortPendSVHandler                              PendSV_Handler
+#define vPortSVCHandler                                 SVC_Handler
+#define xPortSysTickHandler                             SysTick_Handler
+#endif
+#endif /* FREERTOS_CONFIG_H */