Trustzone Examples on LPC55S6x and MCUXPresso SDK - nxp-mcuxpresso/vscode-for-mcux GitHub Wiki
The following are required to follow this chapter:
- MCUXpresso for VS Code v1.0 or later
- LPCXpresso 55S69 EVK development board
- LPCXpresso 55S69 EVK version 2.13 SDK or later
A conceptual understanding of Arm TrustZone will also help with understanding the features shown in this article. Please also see the community article on TrustZone on the LPC55S6x.
Finally, familiarity with the use of MCUXpresso for VS Code and MCUXpresso SDK installation is assumed.
Overview
In essence, MCUs incorporating Arm TrustZone technology are able to provide system wide isolation between Secure (S) and Non Secure (NS) worlds. Within the Non Secure environment, access to certain operations, peripherals etc. are controlled from the Secure world. This behaviour is delivered by a single CPU with execution time being shared between these two worlds.
Developing for systems using TrustZone features presents a number of challenges in particular providing Secure World services for Non Secure application developers, debugging of both Secure and Non Secure code (projects) and delivering a usage model within the IDE that can be easily used and understood.
The examples supplied with the SDK contain both Secure and Non Secure linked projects and are configured within the IDE to demonstrate development from the point of view of both Secure and Non Secure development.
However, a more typical 'real world' situation may be for developers working on Non Secure project development and treating the Secure world as a 'Black Box' (or Bootloader) that provides a number of explicit secure operations. This use case will be discussed in a subsequent article.
Note: the LPC55S69 is a multicore MCU as in it contains two physical CPUs - numbered 0 and 1. In these examples all code is targeted at CPU 0, and the use of CPU 1 is outside the scope of this article.
Importing (Linked) Example Project
First, ensure you have installed SDK version (at least) 2.13 for the LPCXpresso55S69 EVK board into MCUXpresso for VS Code. Once installed it will be visible within the Installed SDKs view and its version shown as below (either as GitHub repo or as a standalone SDK):
Also, use MCUXpresso Installer to install at least ARM GNU toolchain component plus a Debug Probe software dedicated for your available debug probe (LinkServer, SEGGER J-Link, or PEmicro).
From the Quickstart view, select the 'Import Example from Repository', then select the installed repository, toolchain, and the LPCXpresso55S69 board.
On "Choose a template" section, type "trustzone", the filter will display only the examples containing the word "trustzone" and select either of the Hello World projects.
Since these projects are linked, both the Secure (_s) and Non Secure (_ns) examples will be imported once the Create button is pressed.
Note: Linked projects are decorated with blue double-ring icon. Also, the tooltip indicates the linked projects as a list, marked by "Linked projects" label. This project linkage is set because the Non Secure project relies on Secure project for access to allowed Secure operations (calls). Where as the Secure project references the Non Secure (and vice-versa) project for debug operations (flash programming).
Once imported, the PROJECT view contains the projects as expected.
Project Settings Exploration
Memory Configuration
The memory allocation of each project can be seen in the Memory node of each project in the PROJECTS view. From here you can see the input memory ranges set (for each project):
Apart from the veneer table, these projects can be considered as separate entities and must have non overlapping memory regions.
Secure: A feature of the address space security is that the setting of address bit 28 signifies a secure location (odd numbers in the most significant nibble).
The SG_veneer_table block at 0x1000FE00 is used for code to provide a gateway to (certain) secure functions and inherits the same flash driver.
Non Secure: For these addresses, bit 28 is not set signifying non secure locations (even numbers in the most significant nibble)
Project Properties
TrustZone capable MCUs have a number of dedicated Project Properties primarily addressing linkage and debug.
A project set to be Secure will generate an additional Secure Gateway Import Library (in project directory -> armgcc/flags.cmake).
Also observe the project directory -> .vscode/mcuxpresso-tools.json
files. They describe linkedProjects
and trustZoneType
options which define the link between secure/non-secure projects and their types used for build and debug options.
Non Secure: Below is shown the Secure Gateway Import Library references the Secure projects generated library location.
Building the Example Projects
Building the examples is as simple as selecting the project and clicking Build icon. Be aware that building the Non Secure project will force the Secure project to build first to provide linkage to the Secure Gateway library and also, building Secure project will force Non Secure project to build at the end. This ensure that single Build operation will trigger full application generation in one step.
Assuming neither project has been built before, building the Non Secure Hello World project will result in the generation of both Secure and Non Secure .elf(s) and generate the output as below:
[build] [22/22 100% :: 2.771] Linking C executable hello_world_ns.elf
[build] Memory region Used Size Region Size %age Used
[build] m_interrupts: 304 B 512 B 59.38%
[build] m_text: 4704 B 400896 B 1.17%
[build] m_core1_image: 0 GB 174 KB 0.00%
[build] m_data: 3200 B 170 KB 1.84%
[build] rpmsg_sh_mem: 0 GB 0 GB
[build] m_usb_sram: 0 GB 16 KB 0.00%
[build] [25/25 100% :: 1.787] Linking C executable hello_world_s.elf
[build] Memory region Used Size Region Size %age Used
[build] m_interrupts: 304 B 512 B 59.38%
[build] m_text: 15136 B 63 KB 23.46%
[build] m_veneer_table: 32 B 512 B 6.25%
[build] m_core1_image: 0 GB 174 KB 0.00%
[build] m_data: 3208 B 32 KB 9.79%
[build] rpmsg_sh_mem: 0 GB 0 GB
[build] m_usb_sram: 0 GB 16 KB 0.00%
Note: In this version of the extension, it is not possible to see both compile logs in the same build session. If you want to see the first building project log in particular, temporary remove the linkedProjects option from project directory ->
.vscode/mcuxpresso-tools.json
then build it individually. This capability of inspecting multiple project logs will be implemented in a future release.
Debugging the Example Projects
As already mentioned, these examples demonstrate development from the point of view of both Secure and Non Secure projects. Hence the initial flow is intended to show startup within the Secure world and then migrate to the Non Secure world.
Therefore, begin by selecting the Secure Project in the PROJECTS view and select Debug option.
Note: If this is the first time this project has been debugged, you will be presented with the option to select a debug probe. If there is a single available debug probe connected, then this will be automatically selected with no further confirmation.
First, the Non Secure binary will be programmed into flash memory - this automatic step will proceed like a normal binary programming operation.
Secondly, the Secure project will then be programmed in the normal way.
Once programming is complete, you should arrive at the default Breakpoint on main within the Secure world as below:
Put a breakpoint on line 68, where the call TZM_JumpToNormalWorld to normal world is. This project will first perform some board/MCU initialisation and print a greeting (as below).
Next, TZM_JumpToNormalWorld function will setup the environment for the Non Secure project .
Note: this step is necessary because the non secure project is not run from reset, so it cannot rely on the default hardware behaviour for initialisation of Stack, Interrupt handlers etc. This is essentially the same operation that a bootloader would perform.
Note: since the non secure project is not debugged directly, it will have no default breakpoint on its main function. To explore the execution, it is recommended to open the Non Secure projects Source -> hello_world_ns.c and manually set a breakpoint, then execute to it, as shown below:
Finally, click Continue button to run this example.
Note: the significance of this example is that the String Compare operation was supplied to the Non Secure project by the Secure project and accessed securely via the Non Secure Entry (NSE).
This step concludes the expected use of this example.
Another mode of operation is to perform a Debug operation directly on the Non Secure project. This is a perfectly valid operation provided the Secure project has first been programmed into flash. If so, the Non Secure project will behave like a standard project and arrive at the breakpoint on main().
If Debug operations fail...
It is possible to program an image into flash that when run prevents further debug operations succeeding. Should this occur, please follow the steps below:
- Terminate debug session
- Disconnect the USB cable from your board to remove power
- Place a jumper on the ISP header (J10) - this will prevent the board booting the image in flash by forcing the MCU to enter ISP mode
- Now reconnect the USB cable to Debug Link connector (P6)
- Select Flash Programmer (from QuickStart Panel view) - and use this to mass erase the flash
If this succeeds, then:
- Disconnect the USB cable from your board
- Remove the jumper on the ISP header (J10)
- Now reconnect the USB cable to Debug Link connector (P6)
Try starting a debug session for your project again using the Debug button from projects' toolbar. If this problem occurs as part of application development, try programming a known working example to ensure there are no underlying problems.