Skip to content

Commit

Permalink
ml-eval-kit: Build individual libraries
Browse files Browse the repository at this point in the history
Instead of building the whole project as an external project,
only build the necessary libraries.

Rename BuildMLEmbeddedEvaluationKit.cmake to
SetupMlEmbeddedEvaluationKitLibraries.cmake

This change also uses the NPU driver component from
ML Evaluation Kit which results in the following changes:
* Modify initialization of NPU in AI applications to use
  API provided by the component
* Add ICache and DCache enablement options as caches are used
  in the NPU component
* Include various patches for the NPU component.
* Remove ML Evaluation Kit device drivers header files
  inclusions as they are no longer used as we are now using
  the NPU component for initializing the NPU.

Signed-off-by: Gabor Abonyi <[email protected]>
  • Loading branch information
GaborAbonyi committed Feb 6, 2024
1 parent 068a167 commit c4b2e83
Show file tree
Hide file tree
Showing 22 changed files with 458 additions and 606 deletions.
1 change: 1 addition & 0 deletions .github/.cSpellWords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ IDAQAB
indet
inkey
iotdeviceadvisor
IRQN
ISRAM
istty
JITP
Expand Down
37 changes: 15 additions & 22 deletions applications/keyword_detection/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023 Arm Limited and/or its affiliates
# Copyright 2023-2024 Arm Limited and/or its affiliates
# <[email protected]>
# SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -31,35 +31,31 @@ set(MCUBOOT_IMAGE_VERSION_NS_UPDATE "0.0.1+20")

# Hardware platform specific setup
if (${ARM_CORSTONE_BSP_TARGET_PLATFORM} STREQUAL "corstone310")
set(ML_TARGET_SUBSYSTEM "sse-310")
set(ETHOS_U_NPU_ID "U55")
set(ETHOS_U_NPU_CONFIG_ID "H256")
set(ETHOSU_TARGET_NPU_CONFIG "ethos-u55-256")
set(ETHOS_U_NPU_MEMORY_MODE Shared_Sram)
set(TFM_PLATFORM_LOCAL_PATH "arm/mps3/corstone310/fvp")
elseif (${ARM_CORSTONE_BSP_TARGET_PLATFORM} STREQUAL "corstone300")
set(ML_TARGET_SUBSYSTEM "sse-300")
set(ETHOS_U_NPU_ID "U55")
set(ETHOS_U_NPU_CONFIG_ID "H128")
set(ETHOSU_TARGET_NPU_CONFIG "ethos-u55-128")
set(ETHOS_U_NPU_MEMORY_MODE Shared_Sram)
set(TFM_PLATFORM_LOCAL_PATH "arm/mps3/corstone300/fvp")
else()
message(FATAL_ERROR "Invalid ARM_CORSTONE_BSP_TARGET_PLATFORM (${ARM_CORSTONE_BSP_TARGET_PLATFORM}) set. Supported are corstone300/corstone310")
endif()

set(TFM_FLASH_S_PARTITION_SIZE "0x40000")
set(TFM_FLASH_NS_PARTITION_SIZE "0x340000")

# Machine Learning setup
set(ML_CMAKE_ARGS
-DTARGET_SUBSYSTEM=${ML_TARGET_SUBSYSTEM}
-DETHOS_U_NPU_CONFIG_ID=${ETHOS_U_NPU_CONFIG_ID}
-DETHOSU_TARGET_NPU_CONFIG=${ETHOSU_TARGET_NPU_CONFIG}
-DUSE_CASE_BUILD=kws
)
if (${ML_INFERENCE_ENGINE} STREQUAL "ETHOS")
list(APPEND ML_CMAKE_ARGS -DETHOS_U_NPU_ENABLED=ON)
set(ETHOS_U_NPU_ENABLED ON)
set(ETHOS_U_NPU_TIMING_ADAPTER_ENABLED OFF)
else()
list(APPEND ML_CMAKE_ARGS -DETHOS_U_NPU_ENABLED=OFF)
set(ETHOS_U_NPU_ENABLED OFF)
endif()
set(ML_TARGETS cmsis-dsp tensorflow_build kws)
set(ML_USE_CASE "kws")
set(ML_MODEL "GenerateKWSModel")
set(TFM_FLASH_S_PARTITION_SIZE "0x40000")
set(TFM_FLASH_NS_PARTITION_SIZE "0x340000")
set(TFM_PLATFORM_UPGRADE_STRATEGY "SWAP_USING_SCRATCH")
set(TFM_PLATFORM_CONFIRM_IMAGE ON)

Expand Down Expand Up @@ -114,13 +110,12 @@ add_subdirectory(${IOT_REFERENCE_ARM_CORSTONE3XX_SOURCE_DIR} ${CMAKE_BINARY_DIR}
list(APPEND CMAKE_MODULE_PATH ${IOT_REFERENCE_ARM_CORSTONE3XX_SOURCE_DIR}/components/aws_iot/cmake)
list(APPEND CMAKE_MODULE_PATH ${IOT_REFERENCE_ARM_CORSTONE3XX_SOURCE_DIR}/components/ai/ml_embedded_evaluation_kit/integration/cmake)
list(APPEND CMAKE_MODULE_PATH ${IOT_REFERENCE_ARM_CORSTONE3XX_SOURCE_DIR}/components/security/trusted_firmware-m/integration/cmake)
include(BuildMlEmbeddedEvaluationKit)
include(SetupMlEmbeddedEvaluationKitLibraries)
include(ConvertAudioSourceToCode)
include(GenerateAWSUpdateDigestAndSignature)
include(MergeTfmImages)
include(SignTfmImage)

add_subdirectory(../libraries/ml-kit ${CMAKE_BINARY_DIR}/libraries/ml-kit)
add_subdirectory(configs ${CMAKE_BINARY_DIR}/Config)
add_subdirectory(../helpers helpers)

Expand Down Expand Up @@ -177,9 +172,6 @@ add_dependencies(keyword-detection trusted_firmware-m-build)
# The provision data must be built before the application because
# it provides credentials to connect to AWS.
add_dependencies(keyword-detection provisioning_data_bin)
# The ML Embedded Evaluation Kit must be built before the application because
# it provides the Machine Learning algorithm to detect keywords.
add_dependencies(keyword-detection ml_embedded_evaluation_kit-build)

target_link_libraries(keyword-detection
PRIVATE
Expand All @@ -194,11 +186,12 @@ target_link_libraries(keyword-detection
helpers-events
mbedtls
mbedtls-threading-freertos
ml-kit-kws
ota-for-aws-iot-embedded-sdk
provisioning-lib
tfm-ns-interface
toolchain-override
kws_api
kws_model
)

include(${IOT_REFERENCE_ARM_CORSTONE3XX_SOURCE_DIR}/bsp/cmake/SetLinkerOptions.cmake)
Expand Down
123 changes: 18 additions & 105 deletions applications/keyword_detection/ml_interface.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright 2021-2023 Arm Limited and/or its affiliates
/* Copyright 2021-2024 Arm Limited and/or its affiliates
* <[email protected]>
* SPDX-License-Identifier: MIT
*/
Expand All @@ -10,10 +10,15 @@

#include "ml_interface.h"
#include "AudioUtils.hpp"
#include "AppContext.hpp"
#include "BufAttributes.hpp"
#include "demo_config.h"
extern "C" {
#include "events.h"
#ifdef USE_ETHOS
#include "ethosu_driver.h"
#include "ethosu_npu_init.h"
#endif
}
#include "KwsClassifier.hpp"
#include "KwsProcessing.hpp"
Expand All @@ -24,13 +29,7 @@ extern "C" {
#include "MicroNetKwsModel.hpp"
#include "mqtt_agent_task.h"
#include "TensorFlowLiteMicro.hpp"
#include "UseCaseCommonUtils.hpp"
#include CMSIS_device_header
#include "device_mps3.h" /* FPGA level definitions and functions. */
#include "ethos-u55.h" /* Mem map and configuration definitions of the Ethos U55 */
#include "ethosu_driver.h" /* Arm Ethos-U55 driver header */
#include "timer_mps3.h" /* Timer functions. */
#include "timing_adapter.h" /* Driver header of the timing adapter */

#include <algorithm>
#include <array>
Expand Down Expand Up @@ -890,111 +889,25 @@ extern struct ethosu_driver ethosu_drv; /* Default Ethos-U55 device driver */
**/
static int prvArmNpuInit(void);

/**
* @brief Defines the Ethos-U interrupt handler: just a wrapper around the default
* implementation.
**/
extern "C" {
void ETHOS_U55_Handler(void)
{
/* Call the default interrupt handler from the NPU driver */
ethosu_irq_handler(&ethosu_drv);
}
}

/**
* @brief Initialises the NPU IRQ
**/
static void prvArmNpuIrqInit(void)
{
const IRQn_Type ethosu_irqnum = (IRQn_Type)EthosU_IRQn;

/* Enable the IRQ */
NVIC_EnableIRQ(ethosu_irqnum);

LogDebug( ( "EthosU IRQ#: %u, Handler: 0x%p\n", ethosu_irqnum, ETHOS_U55_Handler ) );
}

static int prvArmNpuTimingAdapterInit(void)
{
#if defined(TA0_BASE)
struct timing_adapter ta_0;
struct timing_adapter_settings ta_0_settings = {.maxr = TA0_MAXR,
.maxw = TA0_MAXW,
.maxrw = TA0_MAXRW,
.rlatency = TA0_RLATENCY,
.wlatency = TA0_WLATENCY,
.pulse_on = TA0_PULSE_ON,
.pulse_off = TA0_PULSE_OFF,
.bwcap = TA0_BWCAP,
.perfctrl = TA0_PERFCTRL,
.perfcnt = TA0_PERFCNT,
.mode = TA0_MODE,
.maxpending = 0, /* This is a read-only parameter */
.histbin = TA0_HISTBIN,
.histcnt = TA0_HISTCNT};

if (0 != ta_init(&ta_0, TA0_BASE)) {
LogError( ( "TA0 initialisation failed\n" ) );
return 1;
}

ta_set_all(&ta_0, &ta_0_settings);
#endif /* defined (TA0_BASE) */

#if defined(TA1_BASE)
struct timing_adapter ta_1;
struct timing_adapter_settings ta_1_settings = {.maxr = TA1_MAXR,
.maxw = TA1_MAXW,
.maxrw = TA1_MAXRW,
.rlatency = TA1_RLATENCY,
.wlatency = TA1_WLATENCY,
.pulse_on = TA1_PULSE_ON,
.pulse_off = TA1_PULSE_OFF,
.bwcap = TA1_BWCAP,
.perfctrl = TA1_PERFCTRL,
.perfcnt = TA1_PERFCNT,
.mode = TA1_MODE,
.maxpending = 0, /* This is a read-only parameter */
.histbin = TA1_HISTBIN,
.histcnt = TA1_HISTCNT};

if (0 != ta_init(&ta_1, TA1_BASE)) {
LogError( ( "TA1 initialisation failed\n" ) );
return 1;
}

ta_set_all(&ta_1, &ta_1_settings);
#endif /* defined (TA1_BASE) */

return 0;
}

static int prvArmNpuInit(void)
{
int err = 0;

/* If the platform has timing adapter blocks along with Ethos-U55 core
* block, initialise them here. */
// cppcheck-suppress knownConditionTrueFalse
if (0 != (err = prvArmNpuTimingAdapterInit())) {
SCB_EnableICache();
SCB_EnableDCache();

#if defined(ETHOS_U_NPU_TIMING_ADAPTER_ENABLED)
/* If the platform has timing adapter blocks along with Ethos-U core
* block, initialise them here. */
if (0 != (err = arm_ethosu_timing_adapter_init())) {
LogError( ("Failed to init timing adapter\n") );
return err;
}
#endif /* ETHOS_U_NPU_TIMING_ADAPTER_ENABLED */

/* Initialise the IRQ */
prvArmNpuIrqInit();

/* Initialise Ethos-U55 device */
void *const ethosu_base_address = reinterpret_cast<void *const>(SEC_ETHOS_U55_BASE);

if (0
!= (err = ethosu_init(&ethosu_drv, /* Ethos-U55 driver device pointer */
ethosu_base_address, /* Ethos-U55's base address. */
NULL, /* Pointer to fast mem area - NULL for U55. */
0, /* Fast mem region size. */
0, /* Security enable. */
0))) { /* Privilege enable. */
LogError( ( "failed to initalise Ethos-U55 device\n" ) );
// Initialize the ethos NPU
if (0 != (err = arm_ethosu_npu_init())) {
LogError( ("Failed to init arm npu\n") );
return err;
}

Expand Down
Loading

0 comments on commit c4b2e83

Please sign in to comment.