LPCX presso support

Using LPC55S69 SDK Trustzone examples with MCUXpresso IDE v11.0.0

Blog Post created by LPCX presso support Employee on Jun 12, 2019

This article discusses the use of SDK Trustzone example (Hello World) for the LPC55S69 MCU within MCUXpresso IDE.

 

The following are required to follow this blog post:

 

  1. MCUXpresso IDE Version 11.0.x
  2. LPCXpresso 55S69 EVK development board
  3. LPCXpresso 55S69 EVK version 2.6 SDK

 

Older version of MCUXpresso IDE and/or SDK will have different and inferior performance when used with Trustzone examples and are therefore not recommended.

 

A conceptual understanding of Arm Trustzone will also help understand the features shown in this article. Please also see the community article on Trustzone on the LPC55S6x.

 

Finally, a familiarity with the use of MCUXpresso IDE and 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 version SDK version 2.6 for the LPCXpresso55S69 EVK board into MCUXpresso IDE. Once installed it will be visible within the Installed SDKs view and its version shown as below:

Installed SDK view

 

From the Quickstart view, launch the 'Import SDK example(s)' Wizard, then select the LPCXpresso55S69 board and click <next>

Example Import Selection

 

Expand the trustzone examples and click either of the Hello World projects. Since these projects are linked, both the Secure (_s) and Non Secure (_ns) examples will be selected. Click <finish> to start the import.

 

Note: Linked projects are coloured yellow within the wizard. 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 project for debug operations (flash programming).

 

Project Selection

Once imported, you will see the Project Explorer view contains the projects as expected.

 

Project View

 

Project Settings Exploration

 

Memory Configuration

 

The memory allocation of each project can be seen in the Project Explorer view by opening the Project Settings Node and then the Memory Node. From here you can see the input memory ranges set for the managed linker script mechanism (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).

Memory Usage Secure

 

The flash region PROGRAM_FLASH at 0x10000000 specifies the secure LinkServer flash driver LPC55xx_S.cfx.

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. Note: the name SG_veneer_table is a 'magic' string recognised by the IDE as an option for veneer placement (see later)

 

Non Secure: For these addresses, bit 28 is not set signifying non secure locations (even numbers in the most significant nibble)

Memory Usage Non Secure

The flash region PROGRAM_FLASH at 0x10000 specifies the non secure LinkServer flash driver LPC55xx.cfx.

 

Project Properties

 

Trustzone capable MCUs have a number of dedicated Project Properties primarily addressing linkage and debug.

 

A project set to be Secure will have further options available, including a setting for the location of the Secure veneer table, and check box to cause the generation of the Import Library. An additional Secure Gateway Import Library can also be specified.

 

Secure: Below is shown the MCU Linker -> Trustzone properties dialogue.

 

Note the Secure Gateway Placement (Secure veneers to shared secure operations) is set to use the 'magic' flash memory region (mentioned in the previous section) for placement.

Project Properties Secure

Also observe the MCU Debugger -> Trustzone option. If used (as in this example), this takes the name of the associated non secure project which will then automatically be (built and) programmed when the Secure project debug operation is performed. In addition the symbols for this associated project will be added to allow source level debugging of both projects.

 

When selected, it will look like below:

Project Properties Secure Debug Link

 

Non Secure: Below is shown the MCU Linker -> Trustzone properties dialogue: Note the Secure Gateway Import Library references the Secure projects generated library location.

Project Properties Non Secure

 

Building the Example Projects

 

Building the examples is as simple selecting the project and clicking Build in the Quickstart panel. Be aware that building the Non Secure project will force the Secure project to build first to provide linkage to the Secure Gateway library. 

 

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 .axf(s) and generate the output as below:

Memory region         Used Size  Region Size  %age Used
   PROGRAM_FLASH:       16872 B      65024 B     25.95%
 SG_veneer_table:          32 B        512 B      6.25%
            Ram0:        4388 B        32 KB     13.39%
Finished building target: lpcxpresso55s69_hello_world_s.axf

Memory region         Used Size  Region Size  %age Used
   PROGRAM_FLASH:        7372 B       456 KB      1.58%
            Ram0:        8448 B       172 KB      4.80%            
Finished building target: lpcxpresso55s69_hello_world_ns.axf

 

Note: building the Secure project does not force a build of the Non Secure since there are no build dependencies in this direction.


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 a the Secure world and then the migration to the Non Secure where a secure operation will be performed.

 

Therefore, begin by selecting the Secure Project in the Project Explorer view and clicking Debug in the Quickstart Panel. Since we have the option set to enable the pre-programming of the Non Secure binary there will be two stages to this debug operation.

 

Note: If this is the first time this project has been debugged, you will be presented with the option to select a debug probe. Then, since this is a MultiCore MCU, you must also select the core to use (be sure that this is set to Core 0).

 

First, the Non Secure binary will be programmed into flash memory - this automatic step will proceed like a normal binary programming operation and generate a log associated with Non Secure project, a fragment shown below:

 

Flash variant 'LPC55xx (608KB)' detected (608KB = 19*32K at 0x0)
Writing 7372 bytes to address 0x00010000 in Flash
1 of 1 (  0) Writing pages 2-2 at 0x00010000 with 7372 bytes
(  0) at 00010000: 0 bytes - 0/7372
(100) at 00010000: 8192 bytes - 8192/7372
Erased/Wrote sector  2-2 with 7372 bytes in 122msec
Closing flash driver LPC55xx.cfx
(100) Finished writing Flash successfully.
Flash Write Done
Loaded 0x1CCC bytes in 417ms (about 17kB/s)

 

Secondly, the Secure project will then be programmed in the normal way, this will generate a standard debug log associated with the Secure project, a fragment is shown below: 

 

Note: again if this is the first time, the debug probe and MCU core must be selected. For subsequent debug operations, these options will be remembered.

 

Flash variant 'LPC55xx (608KB) (Secure)' detected (608KB = 19*32K at 0x10000000)
Writing 32 bytes to address 0x1000FE00 in Flash
1000A000 done  25% (8192 out of 32288)
1000C000 done  50% (16384 out of 32288)
1000E000 done  76% (24576 out of 32288)
10010000 done 100% (32768 out of 32288)
Erased/Wrote sector  1-1 with 32 bytes in 709msec
Closing flash driver LPC55xx_S.cfx
Flash Write Done
Flash Program Summary: 16904 bytes in 1.00 seconds (16.59 KB/sec)
Starting execution using system reset and halt target with a stall address
Retask read watchpoint 1 at 0x50000040 for boot ROM stall
Restore internally retasked watch #1 no type address 0x0 (unused)
Note - system reset leaves VTOR at 0x13000000 (not 0x10000000 which a booted image might assume)
Stopped (Was Reset)  [Reset from Unknown]
Stopped: Breakpoint #2

 

Once programming is complete, you should arrive at the default Breakpoint on main within the Secure world as below:

Secure Project Debug

 

Click Run and this project will first perform some board/MCU initialisation, print a greeting (as below), then setup the environment for the Non Secure project to execute.

 

Note: this step is necessary because the non secure project is not run from reset, so 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.

Secure Console

Next, a jump will be made to the Non Secure world.

 

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 as shown below:

 

Non Secure Debug

Reminder, since we have the option set to enable the pre-programming of the Non Secure binary this also enabled the loading of Non Secure symbols (which can be observed in the Secure projects debug launch configuration (shown below). It is the loading of these symbols which enables source level debug of the Non Secure project while we are actually debugging the Secure project.

 

Secure Launch Symbols

 

Finally, click Run to run this example to termination and observe the output.

 

Secure Console Non Secure output

 

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 the breakpoint on main ()... However, if the Secure Project has not been pre-loaded, the debug operation will fail.

 

 

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:

 

  • Click on the "Clean Up debug" button on the main IDE toolbar - this kills any stale low level debug operations
  • 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)
  • Now select a project in the Project Explorer view, and then click on the GUI Flash Tool on the main IDE toolbar - and use this to mass erase the flash. [More details on using the GUI Flash Tools can be found inside the supplied IDE v11.0 User Guide]

 

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)

 

Now try starting a debug session for your project again using the Quickstart Panel's Debug button. If this problem occurs as part of application development, try programming a known working example to ensure there are no underlying problems.

Outcomes