Verified Commit 4145d9ab authored by Vincent Coubard's avatar Vincent Coubard
Browse files

Add OTA support and improve pipeline test.



- Improve README
- Add OTA support into ML application
- Improve build script
- Fix issues with Blinky
- Ensure tests can be run on all environment
Signed-off-by: Vincent Coubard's avatarVincent Coubard <vincent.coubard@arm.com>
parent bcf5d9d7
# This is a basic workflow to help you get started with Actions on CMSIS projects
name: ATS keyword workflow
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main, test-actions ]
pull_request:
branches: [ main, test-actions ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "ci_build_and_test_ats_keyword"
ci_build_and_test_ats_keyword:
# The type of runner that the job will run on
#runs-on: ubuntu-latest
runs-on: self-hosted
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v2
# Cleanup of previous environment
- name: Cleanup of self hosted runner environment
run : |
rm -rf build
rm -rf venv
rm -rf lib/*
git clean -xfd
git reset --hard
# Boostrap the environment
- name: Bootstrap environment
run : |
./bootstrap.sh
# Setup python environment
- name: Setup Python environment
run: |
python3 -m venv venv
source venv/bin/activate
pip3 install click imgtool pytest
# Execute CMSIS Build command to build the executable for a Cortex-M55 using Arm Compiler
- name: Build kws application
run : |
source venv/bin/activate
./build.sh kws
# Execute CMSIS Build command to build the executable for a Cortex-M55 using Arm Compiler
- name: Build blinky application
run : |
source venv/bin/activate
./build.sh blinky
- name: Archive artifacts
uses: actions/upload-artifact@v2
with:
name: binaries
path: |
${{ github.workspace }}/build/bootloader/bl2.axf
${{ github.workspace }}/build/secure_partition/tfm_s.axf
${{ github.workspace }}/build/blinky/tfm_ns.axf
${{ github.workspace }}/build/kws/tfm_ns.axf
- name: Run blinky integration test
run : |
source venv/bin/activate
pytest -s blinky/tests
- name: Run kws integration test
run : |
source venv/bin/activate
pytest -s kws/tests
\ No newline at end of file
[submodule "source/lib/amazon_freertos"]
[submodule "lib/amazon_freertos"]
path = lib/amazon_freertos
url = https://github.com/aws/amazon-freertos.git
[submodule "source/lib/mbedcrypto"]
[submodule "lib/mbedcrypto"]
path = lib/mbedcrypto
url = https://github.com/ARMmbed/mbedtls.git
[submodule "source/lib/mcuboot"]
[submodule "lib/mcuboot"]
path = lib/mcuboot
url = https://github.com/mcu-tools/mcuboot.git
[submodule "source/lib/tf-m"]
[submodule "lib/tf-m"]
path = lib/tf-m
url = https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git
[submodule "source/lib/tfm_test"]
branch = master
[submodule "lib/tfm_test"]
path = lib/tfm_test
url = https://git.trustedfirmware.org/TF-M/tf-m-tests.git
[submodule "source/lib/VHT"]
[submodule "lib/VHT"]
path = lib/VHT
url = https://github.com/ARM-software/VHT
[submodule "source/lib/ml-embedded-evaluation-kit"]
[submodule "lib/ml-embedded-evaluation-kit"]
path = lib/ml-embedded-evaluation-kit
url = https://review.mlplatform.org/ml/ethos-u/ml-embedded-evaluation-kit
......@@ -34,7 +34,19 @@ Follow these simple steps to use this code example's default configuration #3 ke
2. Launch Arm Virtual Hardware Instance
```sh
# TBD
# Ensure aws cli is installed and set up: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html
# The script requires a key pair to be set in AWS to identify instances and start new ones.
# Provisioning of keys is detailed here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html
# Note: The key parameter required by the script is the name of the key pair in AWS.
# Start a new instance.
./scripts/avh_start -k <key pair> start
# Get instances status.
./scripts/avh_start -k <key pair> status
# Terminate an instance. If multiple instance are running, you must provide the instance ID.
./scripts/avh_start -k <key pair> status
```
3. Launch GitHub Self-Hosted Runner
......@@ -48,9 +60,9 @@ Follow these simple steps to use this code example's default configuration #3 ke
# Install runner software
> mkdir actions-runner && cd actions-runner
> curl -o actions-runner-osx-x64-2.283.2.tar.gz -L https://github.com/actions/runner/releases/download/v2.283.2/actions-runner-osx-x64-2.283.2.tar.gz
> echo "d7d026b9bf1cb3f133cf53e79c71c0458a82b3f2bdb0a8859cd386ae18ee7c4a actions-runner-osx-x64-2.283.2.tar.gz" | shasum -a 256 -c
> tar xzf ./actions-runner-osx-x64-2.283.2.tar.gz
> curl -o <actions-runner.tar.gz -L https://github.com/actions/runner/releases/download/<version>/<action-runner>.tar.gz
> echo "<sha> <action-runner>.tar.gz" | shasum -a 256 -c
> tar xzf ./<action-runner>.tar.gz
# Create, configure and run the runner
> ./config.sh --url https://github.com/exampleuser/my-ats-keyword --token <token>
......@@ -60,7 +72,8 @@ Follow these simple steps to use this code example's default configuration #3 ke
> exit
```
4. make a trivial (whitespace) code change and watch the code example compile and run test cases on Arm Virtual Hardware on your ec2 instance
4. make a trivial (whitespace) code change and watch the code example compile and run test cases on Arm Virtual Hardware on your ec2 instance.
Please refer to Github actions [documentation](https://docs.github.com/en/actions) to make additional change to the workflow
```sh
# add whitespace to this file
......@@ -72,14 +85,121 @@ Follow these simple steps to use this code example's default configuration #3 ke
> git push origin master
```
5. To update the application, a set of scripts is included to setup the environment, build applications, run them and test them. These scripts must be executed in the AVH AMI.
```sh
# Synchronize git submodules, setup ML and apply required patches
./script/bootstrap.sh
# The python environment requires extra packages to sign the binaries
pip3 install click imgtool pytest
# Build the blinky or kws application
./script/build.sh <blinky|kws>
# Run the blinky or kws application
./script/build.sh <blinky|kws>
# Launch integration tests
pytest -s <blinky|kws>/tests
```
Alternatively, the projects can be build using [Keil MDK](https://www.arm.com/products/development-tools/embedded-and-software/keil-mdk).
`blinky.uvmpw` and `kws.uvmpw` contains respectively the `blinky` and `kws` project.
# Setting up AWS connectivity
The KWS Demo will attempt to connect to AWS IOT and report ML inference results through an MQTT connection. For this to work you will need a [AWS Account](https://aws.amazon.com/) and setup an IoT thing and set credentials in the application.
## AWS account IoT setup
### Create an IoT thing for your device
1. Login to your account and browse to the [AWS IoT console](https://console.aws.amazon.com/iotv2/).
2. In the left navigation pane, choose **Manage**, and then choose **Things**.
3. If you do not have any IoT things registered in your account, the **You don’t have any things yet** page is displayed. If you see this page, choose **Register** a thing.
4. On the **Creating AWS IoT things** page, choose **Create a single thing**.
5. On the **Add your device to the thing registry** page, type a name for your thing (for example `MyThing`), and then choose **Next**. You will need to add the name later to your C code.
6. On the **Add a certificate for your thing** page, under **One-click certificate creation**, choose **Create certificate**.
7. Download your private key and certificate by choosing the **Download** links for each. Make note of the certificate ID. You need it later to attach a policy to your certificate.
8. Choose **Activate** to activate your certificate. Certificates must be activated prior to use.
### Create a policy and attach it to your thing
1. In the navigation pane of the AWS IoT console, choose **Secure**, and then choose **Policies**.
2. On the **Policies** page, choose **Create** (top right corner).
3. On the **Create a policy** page, enter a name for the policy. In the **Action** box, enter **iot:Connect**, **iot:Publish**, **iot:Subscribe**, **iot:Receive**. The **Resource ARN** box will be auto-filled with your credentials. Replace the part after the last semicolon (`:`) with `*`. Under **Effect**, check the **Allow** box. Click on **Create**.
4. In the left navigation pane of the AWS IoT console, choose **Secure**, and then choose **Certificates**. You should see the certificate that you have created earlier.
5. Click on the three dots in the upper right corner of the certificate and choose **Attach policy**.
6. In the **Attach policies to certificate(s)** window, enable the policy that you have just created and click **Attach**.
## Configure the application to connect to your AWS account
Edit `bsp/aws_configs/aws_clientcredential.h` file and set values of specified user defines.
`clientcredentialMQTT_BROKER_ENDPOINT`
Set this to the endpoint name of your amazon account. To find this go to the navigation pane of the [AWS IoT console](https://console.aws.amazon.com/iotv2/), choose **Settings**. On the **Settings** page, and copy the name of your **Endpoint** (such as `a3xyzzyx.iot.us-east-2.amazonaws.com`).
`clientcredentialIOT_THING_NAME`
Set this to the name of the thing you set (e.g. MyThing).
Next insert the keys that are in the certificates you have downloaded when you created the thing. Edit the file `bsp/aws_configs/aws_clientcredential_keys.h` replacing the existing keys with yours.
`keyCLIENT_CERTIFICATE_PEM`
Replace with contents from `<your-thing-certificate-unique-string>-certificate.pem.crt`.
`keyCLIENT_PRIVATE_KEY_PEM`
Replace with contents from `<your-thing-certificate-unique-string>-private.pem.key`.
`keyCLIENT_PUBLIC_KEY_PEM`
Replace with contents from `<your-thing-certificate-unique-string>-public.pem.key`.
## Observing MQTT connectivity
To see messages being sent by the application:
1. Login to your account and browse to the [AWS IoT console](https://console.aws.amazon.com/iotv2/).
2. In the left navigation panel, choose **Manage**, and then choose **Things**.
3. Select the thing you created, and open the **Activity** tab. This will show the application connecting and subscribing to a topic.
4. Click on the **MQTT test client** button. This will open a new tab.
5. The tab **Subscribe to a topic** should be already selected. Open the **Additional configuration** rollout.
6. In the topic filter field enter the topic name which is a concatenation of the name of your thing (set in clientcredentialIOT_THING_NAME) and `/ml/inference` (e.g. if you thing name is MyThing then it's `MyThing/ml/inference`)
7. In the **MQTT payload display** combo box select `Display payloads as strings (more accurate)`
8. Click the **Subscribe** button. The messages will be shown below.
# Replace DS-CNN
All the ML models supported by the [ML Embedded Eval Kit](All the models supported ) are available to applications. The first step to use another odule is to generate sources files from its labels and `.tflite` model.
```sh
# pseudo cli/commands/steps to replace the keyword model with another model
# example can use a model from the arm model zoo
# steps should be validated by arm prior to release
# Enter the ml example repository
cd lib/ml-embedded-evaluation-kit/
ML_GEN_SRC="generated/<model name>/src"
ML_GEN_INC="generated/<model name>/include"
mkdir -p $ML_GEN_SRC
mkdir -p $ML_GEN_INC
./lib/ml-embedded-evaluation-kit/resources_downloaded/env/bin/python3 scripts/py/gen_labels_cpp.py \
--labels_file resources/<model name>/labels/<label file>.txt \
--source_folder_path $ML_GEN_SRC \
--header_folder_path $ML_GEN_INC \
--output_file_name <model name>_labels
./resources_downloaded/env/bin/python3 scripts/py/gen_model_cpp.py \
--tflite_path resources_downloaded/<model name>/<model>.tflite \
--output_dir $ML_GEN_SRC
```
Models available are present in `./lib/ml-embedded-evaluation-kit/resources_downloaded`.
Pre-integrated source code is available from the `ML Embedded Eval Kit` and can be browsed from `./lib/ml-embedded-evaluation-kit/source/use_case`.
Integrating a new model means integrating its source code and requires update of the build files.
# ML Embedded Eval Kit
Philip Lewer to replace this text with a paragraph for ml embedded eval kit
......@@ -90,12 +210,17 @@ Philip Lewer to replace this text with a paragraph for ml embedded eval kit
# Other Resources
| Repository | Description | | | |
|---------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|---|---|
| [Arm AI Ecosystem Catalog](https://www.arm.com/why-arm/partner-ecosystem/ai-ecosystem-catalog) | Connects you to the right partners, enabling you to build the next generation of AI solutions | | | |
| [Arm ML Model Zoo](https://github.com/ARM-software/ML-zoo) | A collection of machine learning models optimized for Arm IP. | | | |
| [Arm Virtual Hardware Documentation](https://mdk-packs.github.io/VHT-TFLmicrospeech/overview/html/index.html) | Documentation for [Arm Virtual Hardware](https://www.arm.com/products/development-tools/simulation/virtual-hardware) | | | |
| Support | A [community.arm.com](http://community.arm.com/) forum exists for users to post queries. INTERNAL NOTE → they have – already set up on the test environment (link). This will be moved to the live environment on 19th October. | | | |
| Repository | Description |
|---------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Arm AI Ecosystem Catalog](https://www.arm.com/why-arm/partner-ecosystem/ai-ecosystem-catalog) | Connects you to the right partners, enabling you to build the next generation of AI solutions |
| [Arm ML Model Zoo](https://github.com/ARM-software/ML-zoo) | A collection of machine learning models optimized for Arm IP. |
| [Arm Virtual Hardware Documentation](https://mdk-packs.github.io/VHT-TFLmicrospeech/overview/html/index.html) | Documentation for [Arm Virtual Hardware](https://www.arm.com/products/development-tools/simulation/virtual-hardware) |
| [Arm Virtual Hardware Documentation](https://mdk-packs.github.io/VHT-TFLmicrospeech/overview/html/index.html) | Documentation for [Arm Virtual Hardware](https://www.arm.com/products/development-tools/simulation/virtual-hardware) |
| [Arm CMSIS Build](https://arm-software.github.io/CMSIS_5/Build/html/index.html) | Documentation for the build system used by applications in this repository. |
| [AWS FreeRTOS](https://docs.aws.amazon.com/freertos/) | Documentation for AWS FreeRTOS. |
| [AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/what-is-aws-iot.html) | Documentation for AWS IoT. |
| [Trusted Firmware-M](https://tf-m-user-guide.trustedfirmware.org/) | Documentation for Trusted Firmware-M |
| Support | A [community.arm.com](http://community.arm.com/) forum exists for users to post queries. INTERNAL NOTE → they have – already set up on the test environment (link). This will be moved to the live environment on 19th October. |
# License and contributions
......
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ProjectWorkspace xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_mpw.xsd">
<SchemaVersion>1.0</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<WorkspaceName>WorkSpace</WorkspaceName>
<project>
<PathAndName>.\tfm.bootloader.uvprojx</PathAndName>
</project>
<project>
<PathAndName>.\tfm.secure.uvprojx</PathAndName>
</project>
<project>
<PathAndName>.\tfm.blinky_ns.uvprojx</PathAndName>
<NodeIsActive>1</NodeIsActive>
</project>
</ProjectWorkspace>
/*
* Copyright (c) 2021 Arm Limited
*
* 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
*
* http://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 "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#include "tfm_ns_interface.h"
#include "psa/protected_storage.h"
#include "serial.h"
#include "blink_task.h"
#include "ml_interface.h"
enum {
LED1 = 1 << 0,
LED_YES = LED1,
LED2 = 1 << 1,
LED_GO = LED2,
LED3 = 1 << 2,
LED_UP = LED3,
LED4 = 1 << 3,
LED_LEFT = LED4,
LED5 = 1 << 4,
LED_ON = LED5,
LED6 = 1 << 5,
LED_ALIVE = LED6,
LED7 = 1 << 6,
LED8 = 1 << 7,
LED9 = 1 << 8,
LED10 = 1 << 9,
LED_ALL = 0xFF
};
static uint32_t *fpgaio_leds = (uint32_t *)0x49302000;
// Events
typedef enum {
UI_EVENT_BLINK,
UI_EVENT_ML_STATE_CHANGE
} ui_state_event_t;
typedef struct {
ui_state_event_t event;
} ui_msg_t;
static ui_msg_t blink_event = {
UI_EVENT_BLINK
};
static ui_msg_t ml_state_change_event = {
UI_EVENT_ML_STATE_CHANGE
};
// Message queue
static QueueHandle_t ui_msg_queue = NULL;
// Blinking timer
TimerHandle_t blink_timer;
void led_on(uint8_t bits)
{
*fpgaio_leds |= bits;
}
void led_off(uint8_t bits)
{
*fpgaio_leds &= ~bits;
}
void led_toggle(uint8_t bits)
{
*fpgaio_leds ^= bits;
}
static void blink_timer_cb( TimerHandle_t xTimer ) {
// Schedule blink of the led in the event queue
xQueueSend(ui_msg_queue, (void*) &blink_event, 0);
}
/*
* Blink task.
*
* Blinks LEDs.
*
* LED1 on and LED2 off => heard YES
* LED1 off and LED2 off => heard NO
* LED1 off and LED2 blinking => no/unknown input
*/
void blink_task(void *pvParameters)
{
printf("Blink task started\r\n");
// Create the ui event queue
ui_msg_queue = xQueueCreate(
10, // In practive at most two items (blink and ml state change) should be in the queue.
sizeof(ui_msg_t)
);
// Configure the timer
blink_timer = xTimerCreate(
"Blink Timer",
portTICK_PERIOD_MS * 25, // timeout
pdTRUE, // auto reload
( void * ) 0, // initial value
blink_timer_cb
);
// Setup blinking event
led_off(LED_ALL);
// start the blinking timer
xTimerStart(blink_timer, portMAX_DELAY);
while (1) {
ui_msg_t msg;
if(xQueueReceive(ui_msg_queue, &msg, portMAX_DELAY) != pdPASS ) {
continue;
}
switch (msg.event)
{
case UI_EVENT_BLINK:
led_toggle(LED_ALL);
break;
default:
break;
}
}
}
......@@ -71,3 +71,4 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
......@@ -14,37 +14,12 @@
* limitations under the License.
*/
#include "stdio.h"
#include "string.h"
#include "cmsis.h"
#include "serial.h"
#include "print_log.h"
#include "blink_task.h"
#include "ml_interface.h"
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "FreeRTOS_IP.h"
/* includes for TFM */
#include "tfm_ns_interface.h"
#include "psa/protected_storage.h"
#include "psa/crypto.h"
/* includes for IoT Cloud */
#include "iot_mqtt.h"
#include "iot_secure_sockets.h"
#include "iot_network_freertos.h"
#include "iot_logging_task.h"
#include "aws_dev_mode_key_provisioning.h"
extern int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
void (*free_func)( void * ) );
static void * prvCalloc( size_t xNmemb,
size_t xSize );
extern void DEMO_RUNNER_RunDemos( void );
#include "serial.h"
/*
* Semihosting is a mechanism that enables code running on an ARM target
......@@ -63,39 +38,34 @@ __asm(" .global __ARM_use_no_argv\n");
extern uint32_t tfm_ns_interface_init(void);
#define FREERTOS_HIGHEST_TASK_PRIORITY (configMAX_PRIORITIES - 1)
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
/**
* Network information
*/
/* The MAC address array is not declared const as the MAC address will
normally be read from an EEPROM and not hard coded (in real deployed
applications).*/
static uint8_t ucMACAddress[ 6 ] = { 0x00, 0x02, 0xF7, 0x00, 0x74, 0x15 }; // mac of my MPS3 eth
/* Define the network addressing. These parameters will be used if either
ipconfigUDE_DHCP is 0 or if ipconfigUSE_DHCP is 1 but DHCP auto configuration
failed. */
static uint8_t ucIPAddress[ 4 ] = { 192, 168, 1, 215 };
static uint8_t ucNetMask[ 4 ] = { 255, 0, 0, 0 };
static uint8_t ucGatewayAddress[ 4 ] = { 10, 10, 10, 1 };
/* The following is the address of an OpenDNS server. */
static uint8_t ucDNSServerAddress[ 4 ] = { 208, 67, 222, 222 };
psa_key_handle_t xOTACodeVerifyKeyHandle = NULL;
/*
* Main task to run TFM and ethernet communication testing
*/
static void blink_task( void *pvParameters )
{
uint32_t *fpgaio_leds = (uint32_t *)0x49302000;
const TickType_t xDelay = portTICK_PERIOD_MS * 200;
printf("FreeRTOS blink task started\r\n");
while (1) {
*fpgaio_leds = 0xFF;
printf("LED on\r\n");
vTaskDelay(xDelay);
*fpgaio_leds = 0x00;
printf("LED off\r\n");
vTaskDelay(xDelay);
}
}
int main()
{
BaseType_t ret = pdPASS;
tfm_ns_interface_init();
serial_init();
xTaskCreate(blink_task, "blink task", configMINIMAL_STACK_SIZE*2, NULL, tskIDLE_PRIORITY, NULL);
xTaskCreate(blink_task, "test task", configMINIMAL_STACK_SIZE*2, NULL, configMAX_PRIORITIES-2, NULL);
printf("starting scheduler from ns main\r\n");
/* Start the scheduler itself. */
vTaskStartScheduler();
......@@ -106,21 +76,9 @@ int main()
}
/**
* @brief Implements libc calloc semantics using the FreeRTOS heap
*/
static void * prvCalloc( size_t xNmemb, size_t xSize )
{
void * pvNew = pvPortMalloc( xNmemb * xSize );
if( NULL != pvNew )
{
memset( pvNew, 0, xNmemb * xSize );
}
return pvNew;
}
* @brief Defines the Ethos-U interrupt handler: just a wrapper around the default
* implementation.
**/
void arm_npu_irq_handler(void)
{
// Do nothing.
}
......@@ -21,29 +21,34 @@ import pytest
@pytest.fixture
def fvp_path():
yield '/opt/FVP_Corstone_SSE-300_Ethos-U55/models/Linux64_GCC-6.4/FVP_Corstone_SSE-300_Ethos-U55'
yield 'VHT-Corstone-300.x'
@pytest.fixture
def binary_path():
yield os.getcwd() + '/../Objects'
yield os.path.dirname(os.path.abspath(__file__)) + '/../../build'
@pytest.fixture
def vsi_script_path():
yield os.path.dirname(os.path.abspath(__file__)) + '/../../lib/VHT/interface/audio/python'
@pytest.fixture(scope="function")
def fvp(fvp_path, binary_path):
def fvp(fvp_path, binary_path, vsi_script_path):
# Fixture of the FVP, when it returns, the FVP is started and
# traces are accessible through the .stdout of the object returned.
# When the test is terminated, the FVP subprocess is closed.
# Note: It can take few seconds to terminate the FVP
cmdline = [
fvp_path,
'-a', f'cpu0*={binary_path}/bl2.axf',
'--data', f'{binary_path}/tfm_s_signed.bin@0x01000000',
'--data', f'{binary_path}/tfm_ns_signed.bin@0x01060000',