Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/Hello-CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
-a $EXEC \
-f ./../FVP/FVP_Corstone_SSE-300/fvp_config.txt \
-C mps3_board.uart0.out_file=$LOG \
--simlimit 60 --stat
--simlimit 10 --stat

echo "Show simulation UART output for ${{ matrix.toolchain }} ${{ matrix.build_type }}"
cat $LOG
80 changes: 73 additions & 7 deletions .github/workflows/SimpleTZ-CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ on:
- cron: '00 20 * * 6'

jobs:
Build:
TrustZone:
name: TrustZone (${{ matrix.build.type }}, ${{ matrix.compiler.name }})
strategy:
matrix:

compiler: [
{name: AC6, ext: axf}
{name: AC6, ext: axf},
{name: GCC, ext: elf}
]
build: [
{type: Release},
Expand All @@ -46,16 +48,80 @@ jobs:
with:
python-version: '3.14'

- name: Build project CM33_s and CM33_ns for build-type ${{ matrix.build.type }} with ${{ matrix.compiler.name }}
- name: Build secure and non-secure projects
working-directory: ./SimpleTrustZone/
run: cbuild SimpleTZ.csolution.yml --packs --active AVH@${{ matrix.build.type }} --toolchain ${{ matrix.compiler.name }}


- name: Execute project CM33_s and CM33_ns for build-type ${{ matrix.build.type }} with ${{ matrix.compiler.name }} using FVP_MPS2_Cortex-M33
- name: Execute secure and non-secure projects on FVP
working-directory: ./SimpleTrustZone/
run: |
FVP_MPS2_Cortex-M33 \
output="$(FVP_MPS2_Cortex-M33 \
-a ./out/CM33_ns/AVH/${{ matrix.build.type }}/CM33_ns.${{ matrix.compiler.ext }} \
-a ./out/CM33_s/AVH/${{ matrix.build.type }}/CM33_s.${{ matrix.compiler.ext }} \
-f ./../FVP/FVP_MPS2_Cortex-M33/fvp_config.txt \
--stat
--simlimit 10 --stat 2>&1)"
printf '%s\n' "$output"

actual="$(printf '%s\n' "$output" | grep -E '^Jump to non-secure application at 0x[[:xdigit:]]{8}$|^Non-secure application\.\.\.$|^func1\(1\) = 4$|^func2\(func3, 2\) = 9$' | sed -E 's/^(Jump to non-secure application at )0x[[:xdigit:]]{8}$/\1<address>/')"
expected=$'Jump to non-secure application at <address>\nNon-secure application...\nfunc1(1) = 4\nfunc2(func3, 2) = 9'
if [[ "$actual" != "$expected" ]]; then
printf 'Unexpected application output.\nExpected:\n%s\nActual:\n%s\n' "$expected" "$actual"
exit 1
fi

NonSecureOnly:
name: Non-secure only (${{ matrix.build.type }}, ${{ matrix.compiler.name }})
strategy:
matrix:
compiler: [
{name: AC6, ext: axf},
{name: GCC, ext: elf}
]
build: [
{type: Release},
{type: Debug}
]

runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@v7.0.1

- name: Install tools
uses: ARM-software/cmsis-actions/vcpkg@v1.3
with:
config: ".ci/vcpkg-configuration.json"

- name: Activate Arm tool license
uses: ARM-software/cmsis-actions/armlm@v1.3

- name: Set up Python
uses: actions/setup-python@v7.0.0
with:
python-version: '3.14'

- name: Build secure project to create HEX file and CMSE library
working-directory: ./SimpleTrustZone/
run: cbuild SimpleTZ.csolution.yml --packs --context CM33_s.${{ matrix.build.type }}+AVH --toolchain ${{ matrix.compiler.name }}

- name: Build non-secure-only target
working-directory: ./SimpleTrustZone/
run: cbuild SimpleTZ.csolution.yml --context CM33_ns.${{ matrix.build.type }}+AVH-NS-only --toolchain ${{ matrix.compiler.name }}
Comment thread
jkrech marked this conversation as resolved.

- name: Execute non-secure-only target on FVP
working-directory: ./SimpleTrustZone/
run: |
output="$(FVP_MPS2_Cortex-M33 \
-a ./out/CM33_ns/AVH-NS-only/${{ matrix.build.type }}/CM33_ns.${{ matrix.compiler.ext }} \
-a ./out/CM33_s/AVH/${{ matrix.build.type }}/CM33_s.hex \
-f ./../FVP/FVP_MPS2_Cortex-M33/fvp_config.txt \
--simlimit 10 --stat 2>&1)"
printf '%s\n' "$output"

actual="$(printf '%s\n' "$output" | grep -E '^Jump to non-secure application at 0x[[:xdigit:]]{8}$|^Non-secure application\.\.\.$|^func1\(1\) = 4$|^func2\(func3, 2\) = 9$' | sed -E 's/^(Jump to non-secure application at )0x[[:xdigit:]]{8}$/\1<address>/')"
expected=$'Jump to non-secure application at <address>\nNon-secure application...\nfunc1(1) = 4\nfunc2(func3, 2) = 9'
if [[ "$actual" != "$expected" ]]; then
printf 'Unexpected application output.\nExpected:\n%s\nActual:\n%s\n' "$expected" "$actual"
exit 1
fi
12 changes: 9 additions & 3 deletions FVP/FVP_MPS2_Cortex-M33/fvp_config.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
# Parameters:
# instance.parameter=value #(type, mode) default = 'def value' : description : [min..max]
#--------------------------------------------------------------------------------------------------------------------------------------------------
fvp_mps2.mps2_visualisation.disable-visualisation=1 # (bool , init-time) default = '0' : Enable/disable visualisation
cpu0.semihosting-heap_limit=0x0 # (int , init-time) default = '0x10700000' : Virtual address of top of heap : [0x0..0xFFFFFFFF]
fvp_mps2.mps2_visualisation.disable-visualisation=1 # (bool , init-time) default = '0' : Enable/disable visualisation
fvp_mps2.UART0.shutdown_on_eot=1 # (bool , init-time) default = '0' : Shutdown simulation when an EOT (ASCII 4) character is transmitted
fvp_mps2.UART0.out_file=- # (string, init-time) default = '' : Send UART output to stdout
fvp_mps2.UART0.unbuffered_output=1 # (bool , init-time) default = '0' : Disable UART output buffering
fvp_mps2.telnetterminal0.start_telnet=0 # (bool , init-time) default = '1' : Do not launch an external terminal
fvp_mps2.telnetterminal1.start_telnet=0 # (bool , init-time) default = '1' : Do not launch an external terminal
fvp_mps2.telnetterminal2.start_telnet=0 # (bool , init-time) default = '1' : Do not launch an external terminal
cpu0.semihosting-heap_limit=0x0 # (int , init-time) default = '0x10700000' : Virtual address of top of heap : [0x0..0xFFFFFFFF]
cpu0.semihosting-stack_base=0x0 # (int , init-time) default = '0x10700000' : Virtual address of base of descending stack : [0x0..0xFFFFFFFF]
cpu0.semihosting-stack_limit=0x0 # (int , init-time) default = '0x10800000' : Virtual address of stack limit : [0x0..0xFFFFFFFF]
cpu0.ITM=0 # (bool , init-time) default = '1' : Level of instrumentation trace supported. false : No ITM trace included, true: ITM trace included
cpu0.INITSVTOR=0x00000000 # (int , init-time) default = '0x10000000' : Secure vector-table offset at reset : [0x0..0xFFFFFF80]
cpu0.SAU=0x8 # (int , init-time) default = '0x4' : Number of SAU regions (0 => no SAU) : [0x0..0x8]
idau.NUM_IDAU_REGION=0x0 # (int , init-time) default = '0xA' :
fvp_mps2.DISABLE_GATING=1 # (bool , init-time) default = '0' : Disable Memory gating logic
#--------------------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------------------
4 changes: 2 additions & 2 deletions Hello/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ The project is configured for execution on [**Arm Virtual Hardware**](https://de
#### For debug type

```bash
> FVP_Corstone_SSE-300 -f ../FVP/FVP_Corstone_SSE-300/fvp_config.txt -a ./out/Hello/CS300/Debug/Hello.axf
> FVP_Corstone_SSE-300 -f ../FVP/FVP_Corstone_SSE-300/fvp_config.txt -a ./out/Hello/CS300/Debug/Hello.axf --simlimit 10
```

#### For release type

```bash
> FVP_Corstone_SSE-300 -f ../FVP/FVP_Corstone_SSE-300/fvp_config.txt -a ./out/Hello/CS300/Release/Hello.axf
> FVP_Corstone_SSE-300 -f ../FVP/FVP_Corstone_SSE-300/fvp_config.txt -a ./out/Hello/CS300/Release/Hello.axf --simlimit 10
```

### Use this project with Keil Studio
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This is a collection of [CMSIS-Toolbox](https://open-cmsis-pack.github.io/cmsis-

## Tool Requirements

The examples use **CMSIS-Toolbox 2.14.0** or higher. Depending on the example, additional tools include CMake, Ninja, Arm Compiler 6, GCC, CLANG, Arm Virtual Hardware Fixed Virtual Platforms (AVH FVP), and STM32CubeMX. Refer to the README of each example for its specific requirements.
The examples use **CMSIS-Toolbox 2.14.0** or higher; the Native CMake integration template requires version 2.15.0 or higher. Depending on the example, additional tools include CMake, Ninja, Arm Compiler 6, GCC, CLANG, Arm Virtual Hardware Fixed Virtual Platforms (AVH FVP), STM32CubeMX, and West with a Zephyr workspace. Refer to the README of each example or template for its specific requirements.

Refer to [**Installation of the CMSIS-Toolbox**](https://open-cmsis-pack.github.io/cmsis-toolbox/installation) for information on the setup of a development environment with these tools.

Expand All @@ -28,7 +28,7 @@ Examples in this repository:
:------------------------------------|:----------------------------------
[Hello](./Hello) | A simple project to get started. Requires no hardware as it runs on [AVH-FVP](https://github.com/ARM-software/AVH) simulation models.
[DualCore](./DualCore) | Application with multiple processors that runs on the [NXP FRDM-K32L3A6](https://www.keil.arm.com/boards/nxp-frdm-k32l3a6-989d2e5/projects/) board.
[SimpleTrustZone](./SimpleTrustZone) | Simple TrustZone example that shows the concept of secure and non-secure projects. Runs on [AVH-FVP](https://github.com/ARM-software/AVH) simulation models.
[SimpleTrustZone](./SimpleTrustZone) | Simple TrustZone example that shows secure and non-secure projects, including how to use a prebuilt secure image. Runs on [AVH-FVP](https://github.com/ARM-software/AVH) simulation models.
[CubeMX](./CubeMX) | Project that uses [STM32CubeMX](https://github.com/Open-CMSIS-Pack/cmsis-toolbox/tree/main/docs/CubeMX.md) for device configuration and contains a RAM and ROM target.

Each *csolution project* example shows different aspects of the CMSIS-Toolbox. For example, the [CubeMX](./CubeMX) *csolution project* contains two targets that show RAM and ROM execution.
Expand All @@ -43,7 +43,7 @@ The project files contain a list of software packs that are used. When using the

## Template Projects

The directory [Templates](./Templates) contains structural templates for simple single-core, multi-core, TrustZone, and unit-test projects. They are not ready-to-build examples, but may be used as a starting point for an application.
The directory [Templates](./Templates) contains structural templates for simple single-core, multi-core, TrustZone, and unit-test projects. It also contains integration templates for existing [Zephyr applications built with West](./Templates/ZephyrWest) and [native CMake projects](./Templates/NativeCMake). They are not ready-to-build examples, but may be used as a starting point for an application.

## GitHub Action Workflows

Expand Down
3 changes: 3 additions & 0 deletions SimpleTrustZone/CM33_ns/CM33_ns.cproject.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ project:
- group: Non-secure Code
files:
- file: main_ns.c
- file: ../retarget_stdio.c
- group: CMSE Library
files:
- file: $cmse-lib(CM33_s)$
Expand All @@ -18,4 +19,6 @@ project:

components:
- component: CMSIS:CORE
- component: CMSIS-Compiler:CORE
- component: CMSIS-Compiler:STDOUT:Custom
- component: Device:Startup&C Startup
4 changes: 2 additions & 2 deletions SimpleTrustZone/CM33_ns/main_ns.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*---------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>

#include "interface.h" // Interface API

Expand Down Expand Up @@ -52,7 +51,8 @@ int main(void) {
val2 = func2(func3, 2);
printf("func2(func3, 2) = %d\n", val2);

exit(0);
printf("\x04"); // EOT (0x04) stops simulation
fflush(stdout);

while (1);
}
4 changes: 3 additions & 1 deletion SimpleTrustZone/CM33_s/CM33_s.cproject.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ project:
- group: Secure Code
files:
- file: main_s.c
- file: ../retarget_stdio.c
- group: Interface
files:
- file: interface.c

components:
- component: CMSIS:CORE
- component: CMSIS-Compiler:CORE
- component: CMSIS-Compiler:STDOUT:Custom
- component: Device:Startup&C Startup
- component: CMSIS-View:Event Recorder&DAP

output:
type:
- elf
- hex

20 changes: 19 additions & 1 deletion SimpleTrustZone/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,28 @@ The solution provides `Debug` and `Release` target sets. Select the required set

Replace `AC6` with `GCC` to build a target set with the GCC compiler.

## Use an Existing Secure Image

The `AVH-NS-only` target demonstrates the CMSIS-Toolbox concept [Use a Prebuilt Secure Image](https://open-cmsis-pack.github.io/cmsis-toolbox/build-overview/#use-a-prebuilt-secure-image). It builds only `CM33_ns` and reuses two outputs previously generated for the `AVH` target:

- `CM33_s.hex`, which is loaded together with the non-secure application.
- `CM33_s_CMSE_Lib.o`, which provides the secure callable interface used to link the non-secure application.

The existing secure outputs must match the selected build type and compiler. Build the `AVH` target before building the corresponding `AVH-NS-only` target:

```txt
> cbuild SimpleTZ.csolution.yml --packs --active AVH@Debug --toolchain AC6
> cbuild SimpleTZ.csolution.yml --context CM33_ns.Debug+AVH-NS-only --toolchain AC6

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect this to work as well:

cbuild SimpleTZ.csolution.yml --active AVH-NS-only@Debug --toolchain AC6

Unless the toolchain changes in between.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

documented.

```

When using VS Code, first select and build `AVH@Debug` or `AVH@Release` in the Manage Solution view. Then select the matching `AVH-NS-only` target set and build or run it. Building `AVH-NS-only` first in a clean workspace fails because the secure HEX file and CMSE library do not yet exist.

The non-secure executable is listed before the secure HEX file in the target set and FVP invocation. This load order lets the executable configure the debug session before the prebuilt secure image is overlaid.

## Execute the project on Arm Virtual Hardware

```txt
> FVP_MPS2_Cortex-M33 -a ./out/CM33_ns/AVH/Debug/CM33_ns.axf -a ./out/CM33_s/AVH/Debug/CM33_s.axf -f ./../FVP/FVP_MPS2_Cortex-M33/fvp_config.txt --stat
> FVP_MPS2_Cortex-M33 -a ./out/CM33_ns/AVH/Debug/CM33_ns.axf -a ./out/CM33_s/AVH/Debug/CM33_s.axf -f ./../FVP/FVP_MPS2_Cortex-M33/fvp_config.txt --simlimit 10 --stat

telnetterminal0: Listening for serial connection on port 5000
telnetterminal1: Listening for serial connection on port 5001
Expand Down
25 changes: 14 additions & 11 deletions SimpleTrustZone/SimpleTZ.cbuild-pack.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
cbuild-pack:
resolved-packs:
- resolved-pack: ARM::CMSIS@6.1.0
selected-by-pack:
- ARM::CMSIS
- resolved-pack: ARM::CMSIS-View@1.2.0
selected-by-pack:
- ARM::CMSIS-View
- resolved-pack: ARM::Cortex_DFP@1.1.0
selected-by-pack:
- ARM::Cortex_DFP
cbuild-pack:
resolved-packs:
- resolved-pack: ARM::CMSIS@6.1.0
selected-by-pack:
- ARM::CMSIS
- resolved-pack: ARM::CMSIS-Compiler@2.3.0
selected-by-pack:
- ARM::CMSIS-Compiler
- resolved-pack: ARM::CMSIS-View@1.2.0
selected-by-pack:
- ARM::CMSIS-View
- resolved-pack: ARM::Cortex_DFP@1.1.0
selected-by-pack:
- ARM::Cortex_DFP
13 changes: 8 additions & 5 deletions SimpleTrustZone/SimpleTZ.csolution.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ solution:

packs:
- pack: ARM::CMSIS
- pack: ARM::CMSIS-Compiler
- pack: ARM::Cortex_DFP
- pack: ARM::CMSIS-View

Expand All @@ -24,7 +25,7 @@ solution:
name: Arm-FVP
model: FVP_MPS2_Cortex-M33
config-file: ../FVP/FVP_MPS2_Cortex-M33/fvp_config.txt
args: --stat
args: --simlimit 10 --stat
- set: Release
images:
- project-context: CM33_ns.Release
Expand All @@ -33,29 +34,31 @@ solution:
name: Arm-FVP
model: FVP_MPS2_Cortex-M33
config-file: ../FVP/FVP_MPS2_Cortex-M33/fvp_config.txt
args: --stat
args: --simlimit 10 --stat

- type: AVH-NS-only
device: ARM::ARMCM33
target-set:
- set: Debug
images:
- project-context: CM33_ns.Debug
- image: out/CM33_s/AVH/Debug/CM33_s.hex
load: image
- project-context: CM33_ns.Debug
debugger:
name: Arm-FVP
model: FVP_MPS2_Cortex-M33
config-file: ../FVP/FVP_MPS2_Cortex-M33/fvp_config.txt
args: --stat
args: --simlimit 10 --stat
- set: Release
images:
- project-context: CM33_ns.Release
- image: out/CM33_s/AVH/Release/CM33_s.hex
load: image
debugger:
name: Arm-FVP
model: FVP_MPS2_Cortex-M33
config-file: ../FVP/FVP_MPS2_Cortex-M33/fvp_config.txt
args: --stat
args: --simlimit 10 --stat

build-types:
- type: Debug # toolchain options for 'debug'
Expand Down
1 change: 0 additions & 1 deletion SimpleTrustZone/cdefault.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ default:
- -masm=auto
Link:
- --entry=Reset_Handler
- --map
- --info summarysizes
- --summary_stderr
- --diag_suppress=L6314W
Expand Down
40 changes: 40 additions & 0 deletions SimpleTrustZone/retarget_stdio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

/*
* Common stdout retargeting implementation for both the Secure and
* Non-secure parts of the application.
*/

#include <stdint.h>

#include "retarget_stdout.h"

/* UART0 memory-mapped registers used for polling-based output. */
#define UART0_BASE 0x40004000U
#define UART0_DATA (*(volatile uint32_t *)(UART0_BASE + 0x000U))
#define UART0_STATE (*(volatile uint32_t *)(UART0_BASE + 0x004U))
#define UART0_CTRL (*(volatile uint32_t *)(UART0_BASE + 0x008U))
#define UART0_BAUDDIV (*(volatile uint32_t *)(UART0_BASE + 0x010U))

/* Status and control bits required by the transmit path. */
#define UART_TX_FULL (1UL << 0)
#define UART_TX_ENABLE (1UL << 0)

int stdout_putchar(int ch) {
/* Initialize the UART on first use, preserving an existing setup. */
if ((UART0_CTRL & UART_TX_ENABLE) == 0U) {
UART0_BAUDDIV = 16U;
UART0_CTRL = UART_TX_ENABLE;
}

/* Wait until the transmit FIFO has room for the next character. */
while ((UART0_STATE & UART_TX_FULL) != 0U) {
}

UART0_DATA = (uint32_t)(uint8_t)ch;
return ch;
}
1 change: 1 addition & 0 deletions Templates/Multicore/Core0/MyName0.cproject.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ project:

groups:
- group: Source Files
# Add at least one source file
# files:
# - file: main_core0.c
# - file: MyFile1.c
Expand Down
Loading
Loading