Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ml-kit integration #37

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
36 changes: 15 additions & 21 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,12 +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(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 @@ -176,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 @@ -193,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
Loading