diff options
author | Davide Grohmann <davide.grohmann@arm.com> | 2022-05-31 15:24:02 +0200 |
---|---|---|
committer | Kristofer Jonsson <kristofer.jonsson@arm.com> | 2022-06-13 10:35:57 +0000 |
commit | 144b2d2d735d5b2e25894bdeacef7e03761025ad (patch) | |
tree | 39cad431f3f0bbc1491765257d2bd77ddbbf558d | |
parent | 922d2992bbb2dae379bde9b16a3714e19b698dc5 (diff) | |
download | ethos-u-core-platform-144b2d2d735d5b2e25894bdeacef7e03761025ad.tar.gz |
Refactor message_handler app to be more test friendly
Fix importing indexed models, the inclusion of header files was not
working.
Change-Id: Idab7e002abc31f57acc4eda6a2f1cf2defdfd5c4
12 files changed, 379 insertions, 217 deletions
diff --git a/applications/message_handler/CMakeLists.txt b/applications/message_handler/CMakeLists.txt index 040b27d..8d4ef54 100644 --- a/applications/message_handler/CMakeLists.txt +++ b/applications/message_handler/CMakeLists.txt @@ -21,36 +21,34 @@ if (NOT TARGET freertos_kernel) return() endif() +# Split total tensor arena equally for each NPU +if (TARGET ethosu_core_driver AND ETHOSU_TARGET_NPU_COUNT GREATER 0) + set(NUM_ARENAS ${ETHOSU_TARGET_NPU_COUNT}) +else() + set(NUM_ARENAS 1) +endif() + set(MESSAGE_HANDLER_ARENA_SIZE 2000000 CACHE STRING "Total size of all message handler tensor arenas") -set(MESSAGE_HANDLER_MODEL_0 FALSE CACHE STRING "Path to built in model 0") -set(MESSAGE_HANDLER_MODEL_1 FALSE CACHE STRING "Path to built in model 1") -set(MESSAGE_HANDLER_MODEL_2 FALSE CACHE STRING "Path to built in model 2") -set(MESSAGE_HANDLER_MODEL_3 FALSE CACHE STRING "Path to built in model 3") +math(EXPR TENSOR_ARENA_SIZE "${MESSAGE_HANDLER_ARENA_SIZE} / ${NUM_ARENAS}") + +add_subdirectory(lib) + +set(MESSAGE_HANDLER_MODEL_0 "" CACHE STRING "Path to built in model 0") +set(MESSAGE_HANDLER_MODEL_1 "" CACHE STRING "Path to built in model 1") +set(MESSAGE_HANDLER_MODEL_2 "" CACHE STRING "Path to built in model 2") +set(MESSAGE_HANDLER_MODEL_3 "" CACHE STRING "Path to built in model 3") ethosu_add_executable(message_handler SOURCES main.cpp - message_handler.cpp - message_queue.cpp LIBRARIES - cmsis_device - $<$<TARGET_EXISTS:ethosu_core_driver>:ethosu_core_driver> - ethosu_mailbox - freertos_kernel - inference_process) + message_handler_lib + freertos_kernel) target_include_directories(message_handler PRIVATE + indexed_networks ${LINUX_DRIVER_STACK_PATH}/kernel) -# Split total tensor arena equally for each NPU -if (TARGET ethosu_core_driver AND ETHOSU_TARGET_NPU_COUNT GREATER 0) - set(NUM_ARENAS ${ETHOSU_TARGET_NPU_COUNT}) -else() - set(NUM_ARENAS 1) -endif() - -math(EXPR TENSOR_ARENA_SIZE "${MESSAGE_HANDLER_ARENA_SIZE} / ${NUM_ARENAS}") - target_compile_definitions(message_handler PRIVATE TENSOR_ARENA_SIZE=${TENSOR_ARENA_SIZE} $<$<BOOL:${MESSAGE_HANDLER_MODEL_0}>:MODEL_0=${MESSAGE_HANDLER_MODEL_0}> diff --git a/applications/message_handler/indexed_networks/indexed_networks.hpp b/applications/message_handler/indexed_networks/indexed_networks.hpp new file mode 100644 index 0000000..0b6d62a --- /dev/null +++ b/applications/message_handler/indexed_networks/indexed_networks.hpp @@ -0,0 +1,105 @@ +/* + * 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. + */ + +#ifndef INDEXED_NETWORKS_H +#define INDEXED_NETWORKS_H + +#include "networks.hpp" + +#include <cstdio> +#include <inttypes.h> + +#define XSTRINGIFY(src) #src +#define STRINGIFY(src) XSTRINGIFY(src) + +namespace { +#if defined(__has_include) + +#if defined(MODEL_0) +namespace Model0 { +#include STRINGIFY(MODEL_0) +} +#endif + +#if defined(MODEL_1) +namespace Model1 { +#include STRINGIFY(MODEL_1) +} +#endif + +#if defined(MODEL_2) +namespace Model2 { +#include STRINGIFY(MODEL_2) +} +#endif + +#if defined(MODEL_3) +namespace Model3 { +#include STRINGIFY(MODEL_3) +} +#endif + +#endif +} // namespace + +namespace MessageHandler { + +class WithIndexedNetworks : public BaseNetworks<WithIndexedNetworks> { +public: + static bool getIndexedNetwork(const uint32_t index, void *&data, size_t &size) { + switch (index) { +#if defined(MODEL_0) + case 0: + data = reinterpret_cast<void *>(Model0::networkModel); + size = sizeof(Model0::networkModel); + break; +#endif + +#if defined(MODEL_1) + case 1: + data = reinterpret_cast<void *>(Model1::networkModel); + size = sizeof(Model1::networkModel); + break; +#endif + +#if defined(MODEL_2) + case 2: + data = reinterpret_cast<void *>(Model2::networkModel); + size = sizeof(Model2::networkModel); + break; +#endif + +#if defined(MODEL_3) + case 3: + data = reinterpret_cast<void *>(Model3::networkModel); + size = sizeof(Model3::networkModel); + break; +#endif + + default: + printf("Error: Network model index out of range. index=%" PRIu32 "\n", index); + return true; + } + + return false; + } +}; + +} // namespace MessageHandler + +#endif diff --git a/applications/message_handler/model_template.hpp b/applications/message_handler/indexed_networks/network_template.hpp index 353d7d3..353d7d3 100644 --- a/applications/message_handler/model_template.hpp +++ b/applications/message_handler/indexed_networks/network_template.hpp diff --git a/applications/message_handler/lib/CMakeLists.txt b/applications/message_handler/lib/CMakeLists.txt new file mode 100644 index 0000000..7e2826b --- /dev/null +++ b/applications/message_handler/lib/CMakeLists.txt @@ -0,0 +1,36 @@ +# +# Copyright (c) 2020-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. +# + +add_library(message_handler_lib STATIC) + +target_include_directories(message_handler_lib PUBLIC include + PRIVATE ${LINUX_DRIVER_STACK_PATH}/kernel) + +target_link_libraries(message_handler_lib PUBLIC ethosu_mailbox + PRIVATE + cmsis_device + $<$<TARGET_EXISTS:ethosu_core_driver>:ethosu_core_driver> + freertos_kernel + inference_process + tflu) + +target_sources(message_handler_lib PRIVATE + message_handler.cpp + message_queue.cpp + core_driver_mutex.cpp + freertos_allocator.cpp) diff --git a/applications/message_handler/lib/core_driver_mutex.cpp b/applications/message_handler/lib/core_driver_mutex.cpp new file mode 100644 index 0000000..bc043fa --- /dev/null +++ b/applications/message_handler/lib/core_driver_mutex.cpp @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#if defined(ETHOSU) + +#include "FreeRTOS.h" +#include "semphr.h" + +#include <ethosu_driver.h> +#include <stdio.h> + +extern "C" { + +void *ethosu_mutex_create(void) { + return xSemaphoreCreateMutex(); +} + +int ethosu_mutex_lock(void *mutex) { + SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(mutex); + if (xSemaphoreTake(handle, portMAX_DELAY) != pdTRUE) { + printf("Error: Failed to lock mutex.\n"); + return -1; + } + return 0; +} + +int ethosu_mutex_unlock(void *mutex) { + SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(mutex); + if (xSemaphoreGive(handle) != pdTRUE) { + printf("Error: Failed to unlock mutex.\n"); + return -1; + } + return 0; +} + +void *ethosu_semaphore_create(void) { + return xSemaphoreCreateBinary(); +} + +int ethosu_semaphore_take(void *sem) { + SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(sem); + if (xSemaphoreTake(handle, portMAX_DELAY) != pdTRUE) { + printf("Error: Failed to take semaphore.\n"); + return -1; + } + return 0; +} + +int ethosu_semaphore_give(void *sem) { + SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(sem); + if (xPortIsInsideInterrupt()) { + if (xSemaphoreGiveFromISR(handle, NULL) != pdTRUE) { + printf("Error: Failed to give semaphore from ISR.\n"); + return -1; + } + } else { + /* A FreeRTOS binary semaphore is fundamentally a queue that can only hold one item. If the queue is full, + * xSemaphoreGive will return a pdFALSE value. Ignoring the return value in here, as a semaphore give failure + * does not affect the application correctness. */ + if (xSemaphoreGive(handle) != pdTRUE) { + // do nothing + } + } + return 0; +} +} + +#endif diff --git a/applications/message_handler/lib/freertos_allocator.cpp b/applications/message_handler/lib/freertos_allocator.cpp new file mode 100644 index 0000000..c7fdba6 --- /dev/null +++ b/applications/message_handler/lib/freertos_allocator.cpp @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#include "FreeRTOS.h" +#include <cstddef> +#include <new> + +void *operator new(size_t size) { + return pvPortMalloc(size); +} + +void *operator new[](size_t size) { + return pvPortMalloc(size); +} + +void operator delete(void *ptr) { + vPortFree(ptr); +} + +void operator delete(void *ptr, std::size_t) { + vPortFree(ptr); +} + +void operator delete[](void *ptr) { + vPortFree(ptr); +} + +void operator delete[](void *ptr, std::size_t) { + vPortFree(ptr); +} diff --git a/applications/message_handler/message_handler.hpp b/applications/message_handler/lib/include/message_handler.hpp index dd05059..3c227be 100644 --- a/applications/message_handler/message_handler.hpp +++ b/applications/message_handler/lib/include/message_handler.hpp @@ -24,6 +24,7 @@ #include "semphr.h" #include "message_queue.hpp" +#include "networks.hpp" #include <ethosu_core_interface.h> #if defined(ETHOSU) #include <ethosu_driver.h> @@ -35,6 +36,7 @@ #include <algorithm> #include <cstddef> #include <cstdio> +#include <inttypes.h> #include <list> #include <vector> @@ -121,7 +123,8 @@ public: Mailbox::Mailbox &mailbox, std::shared_ptr<Queue<EthosU::ethosu_core_inference_req>> inferenceInputQueue, QueueHandle_t inferenceOutputQueue, - SemaphoreHandle_t messageNotify); + SemaphoreHandle_t messageNotify, + std::shared_ptr<Networks> networks); void run(); @@ -148,6 +151,7 @@ private: QueueHandle_t inferenceOutputQueue; SemaphoreHandle_t messageNotify; EthosU::ethosu_core_msg_capabilities_rsp capabilities; + std::shared_ptr<Networks> networks; }; class InferenceHandler { @@ -156,7 +160,8 @@ public: size_t arenaSize, std::shared_ptr<Queue<EthosU::ethosu_core_inference_req>> inferenceInputQueue, QueueHandle_t inferenceOutputQueue, - SemaphoreHandle_t messageNotify); + SemaphoreHandle_t messageNotify, + std::shared_ptr<Networks> networks); void run(); @@ -174,6 +179,7 @@ private: InferenceProcess::InferenceProcess inference; EthosU::ethosu_core_inference_req *currentReq; EthosU::ethosu_core_inference_rsp *currentRsp; + std::shared_ptr<Networks> networks; }; } // namespace MessageHandler diff --git a/applications/message_handler/message_queue.hpp b/applications/message_handler/lib/include/message_queue.hpp index 4140c62..4140c62 100644 --- a/applications/message_handler/message_queue.hpp +++ b/applications/message_handler/lib/include/message_queue.hpp diff --git a/applications/message_handler/lib/include/networks.hpp b/applications/message_handler/lib/include/networks.hpp new file mode 100644 index 0000000..eb01d10 --- /dev/null +++ b/applications/message_handler/lib/include/networks.hpp @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#ifndef NETWORKS_H +#define NETWORKS_H + +#include <ethosu_core_interface.h> + +#include <cstdio> +#include <inttypes.h> + +using namespace EthosU; + +namespace MessageHandler { + +class Networks { +public: + virtual ~Networks() {} + virtual bool getNetwork(const ethosu_core_network_buffer &buffer, void *&data, size_t &size) = 0; +}; + +template <typename T> +class BaseNetworks : public Networks { +public: + bool getNetwork(const ethosu_core_network_buffer &buffer, void *&data, size_t &size) override { + switch (buffer.type) { + case ETHOSU_CORE_NETWORK_BUFFER: + data = reinterpret_cast<void *>(buffer.buffer.ptr); + size = buffer.buffer.size; + return false; + case ETHOSU_CORE_NETWORK_INDEX: + return T::getIndexedNetwork(buffer.index, data, size); + default: + printf("Error: Unsupported network model type. type=%" PRIu32 "\n", buffer.type); + return true; + } + } +}; + +class NoIndexedNetworks : public BaseNetworks<NoIndexedNetworks> { + static bool getIndexedNetwork(const uint32_t index, void *&data, size_t &size) { + printf("Error: Network model index out of range. index=%" PRIu32 "\n", index); + return true; + } +}; + +} // namespace MessageHandler + +#endif diff --git a/applications/message_handler/message_handler.cpp b/applications/message_handler/lib/message_handler.cpp index 4a3938e..7b6377f 100644 --- a/applications/message_handler/message_handler.cpp +++ b/applications/message_handler/lib/message_handler.cpp @@ -30,124 +30,28 @@ #include "semphr.h" #include <cstring> -#include <inttypes.h> #include <vector> -#define XSTRINGIFY(src) #src -#define STRINGIFY(src) XSTRINGIFY(src) - using namespace EthosU; using namespace MessageQueue; -/**************************************************************************** - * Models - ****************************************************************************/ - -namespace { -#if defined(__has_include) - -#if __has_include(STRINGIFY(MODEL_0)) -namespace Model0 { -#include STRINGIFY(MODEL_0) -} -#endif - -#if __has_include(STRINGIFY(MODEL_1)) -namespace Model1 { -#include STRINGIFY(MODEL_1) -} -#endif - -#if __has_include(STRINGIFY(MODEL_2)) -namespace Model2 { -#include STRINGIFY(MODEL_2) -} -#endif - -#if __has_include(STRINGIFY(MODEL_3)) -namespace Model3 { -#include STRINGIFY(MODEL_3) -} -#endif - -#endif -} // namespace - namespace MessageHandler { /**************************************************************************** * IncomingMessageHandler ****************************************************************************/ -namespace { -bool getNetwork(const ethosu_core_buffer &buffer, void *&data, size_t &size) { - data = reinterpret_cast<void *>(buffer.ptr); - size = buffer.size; - return false; -} - -bool getNetwork(const uint32_t index, void *&data, size_t &size) { - switch (index) { -#if __has_include(STRINGIFY(MODEL_0)) - case 0: - data = reinterpret_cast<void *>(Model0::networkModel); - size = sizeof(Model0::networkModel); - break; -#endif - -#if __has_include(STRINGIFY(MODEL_1)) - case 1: - data = reinterpret_cast<void *>(Model1::networkModel); - size = sizeof(Model1::networkModel); - break; -#endif - -#if __has_include(STRINGIFY(MODEL_2)) - case 2: - data = reinterpret_cast<void *>(Model2::networkModel); - size = sizeof(Model2::networkModel); - break; -#endif - -#if __has_include(STRINGIFY(MODEL_3)) - case 3: - data = reinterpret_cast<void *>(Model3::networkModel); - size = sizeof(Model3::networkModel); - break; -#endif - - default: - printf("Error: Network model index out of range. index=%" PRIu32 "\n", index); - return true; - } - - return false; -} - -bool getNetwork(const ethosu_core_network_buffer &buffer, void *&data, size_t &size) { - switch (buffer.type) { - case ETHOSU_CORE_NETWORK_BUFFER: - return getNetwork(buffer.buffer, data, size); - case ETHOSU_CORE_NETWORK_INDEX: - return getNetwork(buffer.index, data, size); - default: - printf("Error: Unsupported network model type. type=%" PRIu32 "\n", buffer.type); - return true; - } -} - -}; // namespace - IncomingMessageHandler::IncomingMessageHandler( EthosU::ethosu_core_queue &_inputMessageQueue, EthosU::ethosu_core_queue &_outputMessageQueue, Mailbox::Mailbox &_mailbox, std::shared_ptr<Queue<EthosU::ethosu_core_inference_req>> _inferenceInputQueue, QueueHandle_t _inferenceOutputQueue, - SemaphoreHandle_t _messageNotify) : + SemaphoreHandle_t _messageNotify, + std::shared_ptr<Networks> _networks) : inputMessageQueue(_inputMessageQueue), outputMessageQueue(_outputMessageQueue), mailbox(_mailbox), inferenceInputQueue(_inferenceInputQueue), - inferenceOutputQueue(_inferenceOutputQueue), messageNotify(_messageNotify) { + inferenceOutputQueue(_inferenceOutputQueue), messageNotify(_messageNotify), networks(_networks) { mailbox.registerCallback(handleIrq, reinterpret_cast<void *>(this)); readCapabilties(capabilities); } @@ -384,7 +288,7 @@ void IncomingMessageHandler::sendNetworkInfoRsp(uint64_t userArg, ethosu_core_ne void *buffer; size_t size; - bool failed = getNetwork(network, buffer, size); + bool failed = networks->getNetwork(network, buffer, size); if (!failed) { failed = parser.parseModel(buffer, @@ -467,9 +371,11 @@ InferenceHandler::InferenceHandler(uint8_t *tensorArena, size_t arenaSize, std::shared_ptr<Queue<EthosU::ethosu_core_inference_req>> _inferenceInputQueue, QueueHandle_t _inferenceOutputQueue, - SemaphoreHandle_t _messageNotify) : + SemaphoreHandle_t _messageNotify, + std::shared_ptr<Networks> _networks) : inferenceInputQueue(_inferenceInputQueue), - inferenceOutputQueue(_inferenceOutputQueue), messageNotify(_messageNotify), inference(tensorArena, arenaSize) {} + inferenceOutputQueue(_inferenceOutputQueue), messageNotify(_messageNotify), inference(tensorArena, arenaSize), + networks(_networks) {} void InferenceHandler::run() { ethosu_core_inference_req req; @@ -537,7 +443,7 @@ void InferenceHandler::runInference(ethosu_core_inference_req &req, ethosu_core_ } bool InferenceHandler::getInferenceJob(const ethosu_core_inference_req &req, InferenceProcess::InferenceJob &job) { - bool failed = getNetwork(req.network, job.networkModel.data, job.networkModel.size); + bool failed = networks->getNetwork(req.network, job.networkModel.data, job.networkModel.size); if (failed) { return true; } diff --git a/applications/message_handler/message_queue.cpp b/applications/message_handler/lib/message_queue.cpp index c3890fe..c3890fe 100644 --- a/applications/message_handler/message_queue.cpp +++ b/applications/message_handler/lib/message_queue.cpp diff --git a/applications/message_handler/main.cpp b/applications/message_handler/main.cpp index 0b4860a..caa778b 100644 --- a/applications/message_handler/main.cpp +++ b/applications/message_handler/main.cpp @@ -29,10 +29,12 @@ #include <stdio.h> #include "ethosu_core_interface.h" +#include "indexed_networks.hpp" #include "message_handler.hpp" #include "message_queue.hpp" -#include <mailbox.hpp> +#include "networks.hpp" +#include <mailbox.hpp> #if defined(MHU_V2) #include <mhu_v2.hpp> #elif defined(MHU_JUNO) @@ -83,94 +85,6 @@ Mailbox::MHUDummy mailbox; } // namespace /**************************************************************************** - * Override new operators to call in FreeRTOS allocator - ****************************************************************************/ - -void *operator new(size_t size) { - return pvPortMalloc(size); -} - -void *operator new[](size_t size) { - return pvPortMalloc(size); -} - -void operator delete(void *ptr) { - vPortFree(ptr); -} - -void operator delete(void *ptr, std::size_t) { - vPortFree(ptr); -} - -void operator delete[](void *ptr) { - vPortFree(ptr); -} - -void operator delete[](void *ptr, std::size_t) { - vPortFree(ptr); -} - -/**************************************************************************** - * Mutex & Semaphore - ****************************************************************************/ - -extern "C" { - -void *ethosu_mutex_create(void) { - return xSemaphoreCreateMutex(); -} - -int ethosu_mutex_lock(void *mutex) { - SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(mutex); - if (xSemaphoreTake(handle, portMAX_DELAY) != pdTRUE) { - printf("Error: Failed to lock mutex.\n"); - return -1; - } - return 0; -} - -int ethosu_mutex_unlock(void *mutex) { - SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(mutex); - if (xSemaphoreGive(handle) != pdTRUE) { - printf("Error: Failed to unlock mutex.\n"); - return -1; - } - return 0; -} - -void *ethosu_semaphore_create(void) { - return xSemaphoreCreateBinary(); -} - -int ethosu_semaphore_take(void *sem) { - SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(sem); - if (xSemaphoreTake(handle, portMAX_DELAY) != pdTRUE) { - printf("Error: Failed to take semaphore.\n"); - return -1; - } - return 0; -} - -int ethosu_semaphore_give(void *sem) { - SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(sem); - if (xPortIsInsideInterrupt()) { - if (xSemaphoreGiveFromISR(handle, NULL) != pdTRUE) { - printf("Error: Failed to give semaphore from ISR.\n"); - return -1; - } - } else { - /* A FreeRTOS binary semaphore is fundamentally a queue that can only hold one item. If the queue is full, - * xSemaphoreGive will return a pdFALSE value. Ignoring the return value in here, as a semaphore give failure - * does not affect the application correctness. */ - if (xSemaphoreGive(handle) != pdTRUE) { - // do nothing - } - } - return 0; -} -} - -/**************************************************************************** * Application ****************************************************************************/ namespace { @@ -179,13 +93,16 @@ struct TaskParams { TaskParams() : messageNotify(xSemaphoreCreateBinary()), inferenceInputQueue(std::make_shared<Queue<ethosu_core_inference_req>>()), - inferenceOutputQueue(xQueueCreate(10, sizeof(ethosu_core_inference_rsp))) {} + inferenceOutputQueue(xQueueCreate(10, sizeof(ethosu_core_inference_rsp))), + networks(std::make_shared<WithIndexedNetworks>()) {} SemaphoreHandle_t messageNotify; // Used to pass inference requests to the inference runner task std::shared_ptr<Queue<ethosu_core_inference_req>> inferenceInputQueue; // Queue for message responses to the remote host QueueHandle_t inferenceOutputQueue; + // Networks provider + std::shared_ptr<Networks> networks; }; struct InferenceTaskParams { @@ -207,7 +124,8 @@ void inferenceTask(void *pvParameters) { arenaSize, params->taskParams->inferenceInputQueue, params->taskParams->inferenceOutputQueue, - params->taskParams->messageNotify); + params->taskParams->messageNotify, + params->taskParams->networks); process.run(); } @@ -221,7 +139,8 @@ void messageTask(void *pvParameters) { mailbox, params->inferenceInputQueue, params->inferenceOutputQueue, - params->messageNotify); + params->messageNotify, + params->networks); #ifdef MHU_IRQ // Register mailbox interrupt handler |