5.2.1 - Updated I2C files

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Committer:
jacobjohnson
Date:
Mon Feb 27 17:45:05 2017 +0000
Revision:
1:f30bdcd2b33b
Parent:
0:098463de4c5d
changed the inputscale from 1 to 7 in analogin_api.c.  This will need to be changed later, and accessed from the main level, but for now this allows the  adc to read a value from 0 to 3.7V, instead of just up to 1V.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
group-onsemi 0:098463de4c5d 1 # Quick-Start Guide for uVisor on mbed OS
group-onsemi 0:098463de4c5d 2
group-onsemi 0:098463de4c5d 3 This guide will help you get started with uVisor on mbed OS by walking you through creating a sample application for the NXP FRDM-K64F board.
group-onsemi 0:098463de4c5d 4
group-onsemi 0:098463de4c5d 5 The uVisor provides sandboxed environments and resources protection for applications built for ARM Cortex-M3 and Cortex-M4 devices. Here we will show you how to enable the uVisor and configure a secure box to get hold of some exclusive resources (memory, peripherals, interrupts). For more information on the uVisor design philosophy, please check out our the uVisor [introductory document](../../README.md).
group-onsemi 0:098463de4c5d 6
group-onsemi 0:098463de4c5d 7 ## Overview
group-onsemi 0:098463de4c5d 8
group-onsemi 0:098463de4c5d 9 To get a basic `blinky` application running on mbed OS with uVisor enabled, you will need the following:
group-onsemi 0:098463de4c5d 10
group-onsemi 0:098463de4c5d 11 * A platform and a toolchain supported by uVisor on mbed OS. You can verify this on [the official list](../../README.md#supported-platforms). Please note that uVisor might support some platform internally, but not on mbed OS. Generally this means that the porting process has only been partially completed. If you want to port your platform to uVisor and enable it on mbed OS, please follow the [uVisor Porting Guide for mbed OS](../core/PORTING.md).
group-onsemi 0:098463de4c5d 12 * git. It will be used to download the mbed codebase.
group-onsemi 0:098463de4c5d 13 * The mbed command-line tools, mbed-cli. You can run `pip install mbed-cli` to install them.
group-onsemi 0:098463de4c5d 14
group-onsemi 0:098463de4c5d 15 For the remainder of this guide we will assume the following:
group-onsemi 0:098463de4c5d 16
group-onsemi 0:098463de4c5d 17 * You are developing on a \*nix machine, in the `~/code` folder.
group-onsemi 0:098463de4c5d 18 * You are building the app for the [NXP FRDM-K64F](http://developer.mbed.org/platforms/FRDM-K64F/) target, with the [GCC ARM Embedded](https://launchpad.net/gcc-arm-embedded) toolchain.
group-onsemi 0:098463de4c5d 19
group-onsemi 0:098463de4c5d 20 The instructions provided can be easily generalized to the case of other targets on other host OSs.
group-onsemi 0:098463de4c5d 21
group-onsemi 0:098463de4c5d 22 ## Start with the `blinky` app
group-onsemi 0:098463de4c5d 23 [Go to top](#overview)
group-onsemi 0:098463de4c5d 24
group-onsemi 0:098463de4c5d 25 To create a new mbed application called `uvisor-example` just run the following commands:
group-onsemi 0:098463de4c5d 26
group-onsemi 0:098463de4c5d 27 ```bash
group-onsemi 0:098463de4c5d 28 $ cd ~/code
group-onsemi 0:098463de4c5d 29 $ mbed new uvisor-example
group-onsemi 0:098463de4c5d 30 ```
group-onsemi 0:098463de4c5d 31
group-onsemi 0:098463de4c5d 32 The mbed-cli tools will automatically fetch the mbed codebase for you. By default, git will be used to track your code changes, so your application will be ready to be pushed to a git server, if you want to.
group-onsemi 0:098463de4c5d 33
group-onsemi 0:098463de4c5d 34 Once the import process is finished, create a `source` folder:
group-onsemi 0:098463de4c5d 35 ```bash
group-onsemi 0:098463de4c5d 36 $ mkdir ~/code/uvisor-example/source
group-onsemi 0:098463de4c5d 37 ```
group-onsemi 0:098463de4c5d 38 and place a new file `main.cpp` in it:
group-onsemi 0:098463de4c5d 39
group-onsemi 0:098463de4c5d 40 ```C
group-onsemi 0:098463de4c5d 41 /* ~/code/uvisor-example/source/main.cpp */
group-onsemi 0:098463de4c5d 42
group-onsemi 0:098463de4c5d 43 #include "mbed.h"
group-onsemi 0:098463de4c5d 44 #include "rtos.h"
group-onsemi 0:098463de4c5d 45
group-onsemi 0:098463de4c5d 46 DigitalOut led(LED1);
group-onsemi 0:098463de4c5d 47
group-onsemi 0:098463de4c5d 48 int main(void)
group-onsemi 0:098463de4c5d 49 {
group-onsemi 0:098463de4c5d 50 while (true) {
group-onsemi 0:098463de4c5d 51 led = !led;
group-onsemi 0:098463de4c5d 52 Thread::wait(500);
group-onsemi 0:098463de4c5d 53 }
group-onsemi 0:098463de4c5d 54 }
group-onsemi 0:098463de4c5d 55 ```
group-onsemi 0:098463de4c5d 56
group-onsemi 0:098463de4c5d 57 This simple application just blinks an LED from the main thread, which is created by default by the OS.
group-onsemi 0:098463de4c5d 58
group-onsemi 0:098463de4c5d 59 ---
group-onsemi 0:098463de4c5d 60
group-onsemi 0:098463de4c5d 61 **Checkpoint**
group-onsemi 0:098463de4c5d 62
group-onsemi 0:098463de4c5d 63 Compile the application:
group-onsemi 0:098463de4c5d 64
group-onsemi 0:098463de4c5d 65 ```bash
group-onsemi 0:098463de4c5d 66 $ mbed compile -m K64F -t GCC_ARM
group-onsemi 0:098463de4c5d 67 ```
group-onsemi 0:098463de4c5d 68
group-onsemi 0:098463de4c5d 69 The resulting binary will be located at:
group-onsemi 0:098463de4c5d 70
group-onsemi 0:098463de4c5d 71 ```bash
group-onsemi 0:098463de4c5d 72 ~/code/uvisor-example/.build/K64F/GCC_ARM/uvisor-example.bin
group-onsemi 0:098463de4c5d 73 ```
group-onsemi 0:098463de4c5d 74
group-onsemi 0:098463de4c5d 75 Drag-and-drop it onto the USB device mounted on your computer in order to flash the device. When the flashing process is completed, press the reset button on the device. You should see the device LED blinking.
group-onsemi 0:098463de4c5d 76
group-onsemi 0:098463de4c5d 77 ---
group-onsemi 0:098463de4c5d 78
group-onsemi 0:098463de4c5d 79 In the next sections you will see:
group-onsemi 0:098463de4c5d 80
group-onsemi 0:098463de4c5d 81 * How to [enable uVisor](#enable-uvisor) on the `uvisor-example` app.
group-onsemi 0:098463de4c5d 82 * How to [add a secure box](#add-a-secure-box) to the `uvisor-example` app with exclusive access to a timer, to a push-button interrupt, and to static and dynamic memories.
group-onsemi 0:098463de4c5d 83
group-onsemi 0:098463de4c5d 84 ## Enable uVisor
group-onsemi 0:098463de4c5d 85 [Go to top](#overview)
group-onsemi 0:098463de4c5d 86
group-onsemi 0:098463de4c5d 87 To enable the uVisor on the app, just add the following lines at the beginning of the `main.cpp` file:
group-onsemi 0:098463de4c5d 88
group-onsemi 0:098463de4c5d 89 ```C
group-onsemi 0:098463de4c5d 90 /* ~/code/uvisor-example/source/main.cpp */
group-onsemi 0:098463de4c5d 91
group-onsemi 0:098463de4c5d 92 #include "mbed.h"
group-onsemi 0:098463de4c5d 93 #include "rtos.h"
group-onsemi 0:098463de4c5d 94 #include "uvisor-lib/uvisor-lib.h"
group-onsemi 0:098463de4c5d 95
group-onsemi 0:098463de4c5d 96 /* Register privleged system hooks.
group-onsemi 0:098463de4c5d 97 * This is a system-wide configuration and it is independent from the app, but
group-onsemi 0:098463de4c5d 98 * for the moment it needs to be specified in the app. This will change in a
group-onsemi 0:098463de4c5d 99 * later version: The configuration will be provided by the OS. */
group-onsemi 0:098463de4c5d 100 extern "C" void SVC_Handler(void);
group-onsemi 0:098463de4c5d 101 extern "C" void PendSV_Handler(void);
group-onsemi 0:098463de4c5d 102 extern "C" void SysTick_Handler(void);
group-onsemi 0:098463de4c5d 103 extern "C" uint32_t rt_suspend(void);
group-onsemi 0:098463de4c5d 104 UVISOR_SET_PRIV_SYS_HOOKS(SVC_Handler, PendSV_Handler, SysTick_Handler, rt_suspend);
group-onsemi 0:098463de4c5d 105
group-onsemi 0:098463de4c5d 106 /* Main box Access Control Lists (ACLs). */
group-onsemi 0:098463de4c5d 107 /* Note: These are specific to the NXP FRDM-K64F board. See the section below
group-onsemi 0:098463de4c5d 108 * for more information. */
group-onsemi 0:098463de4c5d 109 static const UvisorBoxAclItem g_main_box_acls[] = {
group-onsemi 0:098463de4c5d 110 /* For the LED */
group-onsemi 0:098463de4c5d 111 {SIM, sizeof(*SIM), UVISOR_TACLDEF_PERIPH},
group-onsemi 0:098463de4c5d 112 {PORTB, sizeof(*PORTB), UVISOR_TACLDEF_PERIPH},
group-onsemi 0:098463de4c5d 113
group-onsemi 0:098463de4c5d 114 /* For messages printed on the serial port. */
group-onsemi 0:098463de4c5d 115 {OSC, sizeof(*OSC), UVISOR_TACLDEF_PERIPH},
group-onsemi 0:098463de4c5d 116 {MCG, sizeof(*MCG), UVISOR_TACLDEF_PERIPH},
group-onsemi 0:098463de4c5d 117 {UART0, sizeof(*UART0), UVISOR_TACLDEF_PERIPH},
group-onsemi 0:098463de4c5d 118 };
group-onsemi 0:098463de4c5d 119
group-onsemi 0:098463de4c5d 120 /* Enable uVisor, using the ACLs we just created. */
group-onsemi 0:098463de4c5d 121 UVISOR_SET_MODE_ACL(UVISOR_ENABLED, g_main_box_acls);
group-onsemi 0:098463de4c5d 122
group-onsemi 0:098463de4c5d 123 /* Rest of the existing app code */
group-onsemi 0:098463de4c5d 124 ...
group-onsemi 0:098463de4c5d 125 ```
group-onsemi 0:098463de4c5d 126
group-onsemi 0:098463de4c5d 127 In the code above we specified 3 elements:
group-onsemi 0:098463de4c5d 128
group-onsemi 0:098463de4c5d 129 1. System-wide uVisor configurations: `UVISOR_SET_PRIV_SYS_HOOKS`. Application authors currently need to specify the privileged system hooks at the application level with this macro, but in the future the operating system will register the privileged system hooks on its own.
group-onsemi 0:098463de4c5d 130 1. Main box Access Control Lists (ACLs). Since with uVisor enabled everything runs in unprivileged mode, we need to make sure that peripherals that are accessed by the OS and the main box are allowed. These peripherals are specified using a list like the one in the snippet above. For the purpose of this example we provide you the list of all the ACLs that we know you will need. For other platforms or other applications you need to determine those ACLs following a process that is described in a [section](#the-main-box-acls) below.
group-onsemi 0:098463de4c5d 131 1. App-specific uVisor configurations: `UVISOR_SET_MODE_ACL`. This macro sets the uVisor mode (enabled) and associates the list of ACLs we just created with the main box.
group-onsemi 0:098463de4c5d 132
group-onsemi 0:098463de4c5d 133 Before compiling, we need to override the original `K64F` target to enable the uVisor feature. To do so, add the file `~/code/uvisor-example/mbed_app.json` with the following content:
group-onsemi 0:098463de4c5d 134
group-onsemi 0:098463de4c5d 135 ```JSON
group-onsemi 0:098463de4c5d 136 {
group-onsemi 0:098463de4c5d 137 "target_overrides": {
group-onsemi 0:098463de4c5d 138 "K64F": {
group-onsemi 0:098463de4c5d 139 "target.features_add": ["UVISOR"],
group-onsemi 0:098463de4c5d 140 "target.extra_labels_add": ["UVISOR_SUPPORTED"]
group-onsemi 0:098463de4c5d 141 }
group-onsemi 0:098463de4c5d 142 },
group-onsemi 0:098463de4c5d 143 "macros": [
group-onsemi 0:098463de4c5d 144 "FEATURE_UVISOR",
group-onsemi 0:098463de4c5d 145 "TARGET_UVISOR_SUPPORTED"
group-onsemi 0:098463de4c5d 146 ]
group-onsemi 0:098463de4c5d 147 }
group-onsemi 0:098463de4c5d 148 ```
group-onsemi 0:098463de4c5d 149
group-onsemi 0:098463de4c5d 150 The macros `FEATURE_UVISOR` and `TARGET_UVISOR_SUPPORTED` in the configuration file above are automatically defined for C and C++ files, but not for assembly files. Since the uVisor relies on those symbols in some assembly code, we need to define them manually.
group-onsemi 0:098463de4c5d 151
group-onsemi 0:098463de4c5d 152 ---
group-onsemi 0:098463de4c5d 153
group-onsemi 0:098463de4c5d 154 **Checkpoint**
group-onsemi 0:098463de4c5d 155
group-onsemi 0:098463de4c5d 156 Compile the application again. This time the `K64F` target will include the new features and labels we provided in `mbed_app.json`;
group-onsemi 0:098463de4c5d 157
group-onsemi 0:098463de4c5d 158 ```bash
group-onsemi 0:098463de4c5d 159 $ mbed compile -m K64F -t GCC_ARM
group-onsemi 0:098463de4c5d 160 ```
group-onsemi 0:098463de4c5d 161
group-onsemi 0:098463de4c5d 162 The binary will be located at:
group-onsemi 0:098463de4c5d 163
group-onsemi 0:098463de4c5d 164 ```bash
group-onsemi 0:098463de4c5d 165 ~/code/uvisor-example/.build/K64F/GCC_ARM/uvisor-example.bin
group-onsemi 0:098463de4c5d 166 ```
group-onsemi 0:098463de4c5d 167
group-onsemi 0:098463de4c5d 168 Re-flash the device and press the reset button. The device LED should be blinking as in the previous case.
group-onsemi 0:098463de4c5d 169
group-onsemi 0:098463de4c5d 170 ---
group-onsemi 0:098463de4c5d 171
group-onsemi 0:098463de4c5d 172 If you enable uVisor in the `blinky` app as it was written above, you will not get any particular security feature. All code and resources share the same security context, which we call the *main box*.
group-onsemi 0:098463de4c5d 173
group-onsemi 0:098463de4c5d 174 A lot happens under the hood, though. All the user code now runs in unprivileged mode, and the systems services like the `NVIC` APIs or the OS SVCalls are routed through the uVisor.
group-onsemi 0:098463de4c5d 175
group-onsemi 0:098463de4c5d 176 ## Add a secure box
group-onsemi 0:098463de4c5d 177 [Go to top](#overview)
group-onsemi 0:098463de4c5d 178
group-onsemi 0:098463de4c5d 179 Now that uVisor is enabled, we can finally add a *secure box*.
group-onsemi 0:098463de4c5d 180
group-onsemi 0:098463de4c5d 181 A secure box is a special compartment that is granted exclusive access to peripherals, memories and interrupts. Private resources are only accessible when the *context* of the secure box is active. The uVisor is the only one that can enable a secure box context, for example upon thread switching or interrupt handling.
group-onsemi 0:098463de4c5d 182
group-onsemi 0:098463de4c5d 183 Code that belongs to a box is not obfuscated by uVisor, so it is still readable and executable from outside of the box. In addition, declaring an object in the same file that configures a secure box does not protect that object automatically.
group-onsemi 0:098463de4c5d 184
group-onsemi 0:098463de4c5d 185 Instead, we provide specific APIs to instruct the uVisor to protect a private resource. Here we will show how to use these APIs in the `uvisor-example` app.
group-onsemi 0:098463de4c5d 186
group-onsemi 0:098463de4c5d 187 ### Configure the secure box
group-onsemi 0:098463de4c5d 188
group-onsemi 0:098463de4c5d 189 For this example, we want to create a secure box called `private_timer`. The `private_timer` box will be configured to have exclusive access to the PIT timer and to the GPIO PORT C on the NXP FRDM-K64F board, which means that other boxes will be prevented from accessing these peripherals.
group-onsemi 0:098463de4c5d 190
group-onsemi 0:098463de4c5d 191 Each secure box must have at least one thread, which we call the box's main thread. In our `private_timer` box we will only use this thread throughout the whole program. The thread will constantly save the current timer value in a private buffer. In addition, we want to print the content of the buffered timer values whenever we press the `SW2` button on the board.
group-onsemi 0:098463de4c5d 192
group-onsemi 0:098463de4c5d 193 We want the box to have exclusive access to the following resources:
group-onsemi 0:098463de4c5d 194
group-onsemi 0:098463de4c5d 195 * The timer and push-button peripherals (as specified by a peripheral ACL). Nobody else should be able to read the timer values.
group-onsemi 0:098463de4c5d 196 * The push-button interrupt (as specified by an IRQ ACL). We want the button IRQ to be re-routed to our box-specific ISR.
group-onsemi 0:098463de4c5d 197 * The buffer that holds the timer samples (as specified by a dynamic memory ACL).
group-onsemi 0:098463de4c5d 198 * The static memory that holds information about the timer buffer (as specified by a static memory ACL).
group-onsemi 0:098463de4c5d 199
group-onsemi 0:098463de4c5d 200 Create a new source file, `~/code/uvisor-example/source/secure_box.cpp`. We will configure the secure box inside this file. The secure box name for this example is `private_timer`.
group-onsemi 0:098463de4c5d 201
group-onsemi 0:098463de4c5d 202 ```C
group-onsemi 0:098463de4c5d 203 /* ~/code/uvisor-example/source/secure_box.cpp */
group-onsemi 0:098463de4c5d 204
group-onsemi 0:098463de4c5d 205 #include "mbed.h"
group-onsemi 0:098463de4c5d 206 #include "rtos.h"
group-onsemi 0:098463de4c5d 207 #include "uvisor-lib/uvisor-lib.h"
group-onsemi 0:098463de4c5d 208
group-onsemi 0:098463de4c5d 209 /* Private static memory for the secure box */
group-onsemi 0:098463de4c5d 210 typedef struct {
group-onsemi 0:098463de4c5d 211 uint32_t * buffer;
group-onsemi 0:098463de4c5d 212 int index;
group-onsemi 0:098463de4c5d 213 } PrivateTimerStaticMemory;
group-onsemi 0:098463de4c5d 214
group-onsemi 0:098463de4c5d 215 /* ACLs list for the secure box: Timer (PIT). */
group-onsemi 0:098463de4c5d 216 static const UvisorBoxAclItem g_private_timer_acls[] = {
group-onsemi 0:098463de4c5d 217 {PIT, sizeof(*PIT), UVISOR_TACLDEF_PERIPH}
group-onsemi 0:098463de4c5d 218 {PORTC, sizeof(*PORTC), UVISOR_TACLDEF_PERIPH},
group-onsemi 0:098463de4c5d 219 };
group-onsemi 0:098463de4c5d 220
group-onsemi 0:098463de4c5d 221 static void private_timer_main_thread(const void *);
group-onsemi 0:098463de4c5d 222
group-onsemi 0:098463de4c5d 223 /* Secure box configuration */
group-onsemi 0:098463de4c5d 224 UVISOR_BOX_NAMESPACE(NULL); /* We won't specify a box namespace for this example. */
group-onsemi 0:098463de4c5d 225 UVISOR_BOX_HEAPSIZE(4096); /* Heap size for the secure box */
group-onsemi 0:098463de4c5d 226 UVISOR_BOX_MAIN(private_timer_main_thread, /* Main thread for the secure box */
group-onsemi 0:098463de4c5d 227 osPriorityNormal, /* Priority of the secure box's main thread */
group-onsemi 0:098463de4c5d 228 1024); /* Stack size for the secure box's main thread */
group-onsemi 0:098463de4c5d 229 UVISOR_BOX_CONFIG(private_timer, /* Name of the secure box */
group-onsemi 0:098463de4c5d 230 g_private_timer_acls, /* ACLs list for the secure box */
group-onsemi 0:098463de4c5d 231 1024, /* Stack size for the secure box */
group-onsemi 0:098463de4c5d 232 PrivateTimerStaticMemory); /* Private static memory for the secure box. */
group-onsemi 0:098463de4c5d 233 ```
group-onsemi 0:098463de4c5d 234
group-onsemi 0:098463de4c5d 235 ### Create the secure box's main thread function
group-onsemi 0:098463de4c5d 236
group-onsemi 0:098463de4c5d 237 In general, you can decide what to do in your box's main thread. You can run it once and then kill it, use it to configure memories, peripherals, or to create other threads. In this app, the box's main thread is the only thread for the `private_timer` box, and it will run throughout the whole program.
group-onsemi 0:098463de4c5d 238
group-onsemi 0:098463de4c5d 239 The `private_timer_main_thread` function configures the PIT timer, allocates the dynamic buffer to hold the timer values and initializes its private static memory, `PrivateTimerStaticMemory`. A spinning loop is used to update the values in the buffer every time the thread is reactivated.
group-onsemi 0:098463de4c5d 240
group-onsemi 0:098463de4c5d 241 ```C
group-onsemi 0:098463de4c5d 242 /* Number of timer samples we will use */
group-onsemi 0:098463de4c5d 243 #define PRIVATE_TIMER_BUFFER_COUNT 256
group-onsemi 0:098463de4c5d 244
group-onsemi 0:098463de4c5d 245 /* For debug purposes: print the buffer values when the SW2 button is pressed. */
group-onsemi 0:098463de4c5d 246 static void private_timer_button_on_press(void)
group-onsemi 0:098463de4c5d 247 {
group-onsemi 0:098463de4c5d 248 for (int i = 0; i < PRIVATE_TIMER_BUFFER_COUNT; i++) {
group-onsemi 0:098463de4c5d 249 printf("buffer[%03d] = %lu\r\n", i, uvisor_ctx->buffer[i]);
group-onsemi 0:098463de4c5d 250 }
group-onsemi 0:098463de4c5d 251 }
group-onsemi 0:098463de4c5d 252
group-onsemi 0:098463de4c5d 253 /* Main thread for the secure box */
group-onsemi 0:098463de4c5d 254 static void private_timer_main_thread(const void *)
group-onsemi 0:098463de4c5d 255 {
group-onsemi 0:098463de4c5d 256 /* Create the buffer and cache its pointer to the private static memory. */
group-onsemi 0:098463de4c5d 257 uvisor_ctx->buffer = (uint32_t *) malloc(PRIVATE_TIMER_BUFFER_COUNT * sizeof(uint32_t));
group-onsemi 0:098463de4c5d 258 if (uvisor_ctx->buffer == NULL) {
group-onsemi 0:098463de4c5d 259 mbed_die();
group-onsemi 0:098463de4c5d 260 }
group-onsemi 0:098463de4c5d 261 uvisor_ctx->index = 0;
group-onsemi 0:098463de4c5d 262
group-onsemi 0:098463de4c5d 263 /* Setup the push-button callback. */
group-onsemi 0:098463de4c5d 264 InterruptIn button(SW2);
group-onsemi 0:098463de4c5d 265 button.mode(PullUp);
group-onsemi 0:098463de4c5d 266 button.fall(&private_timer_button_on_press);
group-onsemi 0:098463de4c5d 267
group-onsemi 0:098463de4c5d 268 /* Setup and start the timer. */
group-onsemi 0:098463de4c5d 269 Timer timer;
group-onsemi 0:098463de4c5d 270 timer.start();
group-onsemi 0:098463de4c5d 271
group-onsemi 0:098463de4c5d 272 while (1) {
group-onsemi 0:098463de4c5d 273 /* Store the timer value. */
group-onsemi 0:098463de4c5d 274 uvisor_ctx->buffer[uvisor_ctx->index] = timer.read_us();
group-onsemi 0:098463de4c5d 275
group-onsemi 0:098463de4c5d 276 /* Update the index. Behave as a circular buffer. */
group-onsemi 0:098463de4c5d 277 if (uvisor_ctx->index < PRIVATE_TIMER_BUFFER_COUNT - 1) {
group-onsemi 0:098463de4c5d 278 uvisor_ctx->index++;
group-onsemi 0:098463de4c5d 279 } else {
group-onsemi 0:098463de4c5d 280 uvisor_ctx->index = 0;
group-onsemi 0:098463de4c5d 281 }
group-onsemi 0:098463de4c5d 282 }
group-onsemi 0:098463de4c5d 283 }
group-onsemi 0:098463de4c5d 284 ```
group-onsemi 0:098463de4c5d 285
group-onsemi 0:098463de4c5d 286 A few things to note in the code above:
group-onsemi 0:098463de4c5d 287
group-onsemi 0:098463de4c5d 288 * If code is running in the context of `private_timer`, then any object instantiated inside that code will belong to the `private_timer` heap and stack. This means that in the example above the `InterruptIn` and `Timer` objects are private to the `private_timer` box. The same applies to the dynamically allocated buffer `uvisor_ctx->buffer`.
group-onsemi 0:098463de4c5d 289 * The content of the private memory `PrivateTimerStaticMemory` can be accessed using the `PrivateTimerStaticMemory * uvisor_ctx` pointer, which is maintained by uVisor.
group-onsemi 0:098463de4c5d 290 * The `InterruptIn` object triggers the registration of an interrupt slot. Since that code is run in the context of the `private_timer` box, then the push-button IRQ belongs to that box. If you want to use the IRQ APIs directly, read the [section](#the-nvic-apis) below.
group-onsemi 0:098463de4c5d 291 * Even if the `private_timer_button_on_press` function runs in the context of `private_timer`, we can still use the `printf` function, which accesses the `UART0` peripheral, owned by the main box. This is because all ACLs declared in the main box are by default shared with all the other secure boxes. This also means that the messages we are printing on the serial port are not secure, because other boxes have access to that peripheral.
group-onsemi 0:098463de4c5d 292
group-onsemi 0:098463de4c5d 293 > **Warning**: Instantiating an object in the `secure_box.cpp` global scope will automatically map it to the main box context, not the `private_timer` one. If you want an object to be private to a box, you need to instantiate it inside the code that will run in the context of that box (like the `InterruptIn` and `Timer` objects), or alternatively statically initialize it in the box private static memory (like the `buffer` and `index` variables in `PrivateTimerStaticMemory`).
group-onsemi 0:098463de4c5d 294
group-onsemi 0:098463de4c5d 295 ---
group-onsemi 0:098463de4c5d 296
group-onsemi 0:098463de4c5d 297 **Checkpoint**
group-onsemi 0:098463de4c5d 298
group-onsemi 0:098463de4c5d 299 Compile the application again:
group-onsemi 0:098463de4c5d 300
group-onsemi 0:098463de4c5d 301 ```bash
group-onsemi 0:098463de4c5d 302 $ mbed compile -m K64F -t GCC_ARM
group-onsemi 0:098463de4c5d 303 ```
group-onsemi 0:098463de4c5d 304
group-onsemi 0:098463de4c5d 305 Re-flash the device, and press the reset button. The device LED should be blinking as in the previous case.
group-onsemi 0:098463de4c5d 306
group-onsemi 0:098463de4c5d 307 If you don't see the LED blinking, it means that the application halted somewhere, probably because uVisor captured a fault. You can setup the uVisor debug messages to see if there is any problem. Follow the [Debugging uVisor on mbed OS](DEBUGGING.md) document for a step-by-step guide.
group-onsemi 0:098463de4c5d 308
group-onsemi 0:098463de4c5d 309 If the LED is blinking, it means that the app is running fine. If you now press the `SW2` button on the NXP FRDM-K64F board, the `private_timer_button_on_press` function will be executed, printing the values in the timer buffer. You can observe these values by opening a serial port connection to the device, with a baud rate of 9600. When the print is completed, you should see the LED blinking again.
group-onsemi 0:098463de4c5d 310
group-onsemi 0:098463de4c5d 311 ### Expose public secure entry points to the secure box
group-onsemi 0:098463de4c5d 312
group-onsemi 0:098463de4c5d 313 Coming soon.
group-onsemi 0:098463de4c5d 314
group-onsemi 0:098463de4c5d 315 ## Wrap-up
group-onsemi 0:098463de4c5d 316 [Go to top](#overview)
group-onsemi 0:098463de4c5d 317
group-onsemi 0:098463de4c5d 318 In this guide we showed you how to:
group-onsemi 0:098463de4c5d 319
group-onsemi 0:098463de4c5d 320 * Enable uVisor on an existing application.
group-onsemi 0:098463de4c5d 321 * Add a secure box to your application.
group-onsemi 0:098463de4c5d 322 * Protect static and dynamic memories in a secure box.
group-onsemi 0:098463de4c5d 323 * Gain exclusive access to a peripheral and an IRQ in a secure box.
group-onsemi 0:098463de4c5d 324 * (Coming soon) Expose public secure entry points to a secure box.
group-onsemi 0:098463de4c5d 325
group-onsemi 0:098463de4c5d 326 You can now modify the example or create a new one to protect your resources into a secure box. You might find the following resources useful:
group-onsemi 0:098463de4c5d 327
group-onsemi 0:098463de4c5d 328 * [uVisor API documentation](API.md)
group-onsemi 0:098463de4c5d 329 * [Debugging uVisor on mbed OS](DEBUGGING.md)
group-onsemi 0:098463de4c5d 330
group-onsemi 0:098463de4c5d 331 If you found any bug or inconsistency in this guide, please [raise an issue](https://github.com/ARMmbed/uvisor/issues/new).
group-onsemi 0:098463de4c5d 332
group-onsemi 0:098463de4c5d 333 ## Appendix
group-onsemi 0:098463de4c5d 334 [Go to top](#overview)
group-onsemi 0:098463de4c5d 335
group-onsemi 0:098463de4c5d 336 This section contains additional information that you might find useful when setting up a secure box.
group-onsemi 0:098463de4c5d 337
group-onsemi 0:098463de4c5d 338 ### The NVIC APIs
group-onsemi 0:098463de4c5d 339
group-onsemi 0:098463de4c5d 340 The ARM CMSIS header files provide APIs to configure, enable and disable IRQs in the NVIC module. These APIs are all prefixed with `NVIC_` and can be found in the `core_cm*.h` files in your CMSIS module.
group-onsemi 0:098463de4c5d 341
group-onsemi 0:098463de4c5d 342 In addition, the CMSIS header also provide APIs to set and get an interrupt vector at runtime. This requires the interrupt vector table, which is usually located in flash, to be relocated to SRAM.
group-onsemi 0:098463de4c5d 343
group-onsemi 0:098463de4c5d 344 When the uVisor is enabled, all NVIC APIs are re-routed to the corresponding uVisor vIRQ APIs, which virtualize the interrupt module. The uVisor interrupt model has the following features:
group-onsemi 0:098463de4c5d 345
group-onsemi 0:098463de4c5d 346 * The uVisor owns the interrupt vector table.
group-onsemi 0:098463de4c5d 347 * All ISRs are relocated to SRAM.
group-onsemi 0:098463de4c5d 348 * Code in a box can only change the state of an IRQ (enable it, change its priority, etc.) if the box registered that IRQ with uVisor at runtime, using the `NVIC_SetVector` API.
group-onsemi 0:098463de4c5d 349 * An IRQ that belongs to a box can only be modified when that box context is active.
group-onsemi 0:098463de4c5d 350
group-onsemi 0:098463de4c5d 351 Although this behaviour is different from the original NVIC one, it is backwards compatible. This means that legacy code (like a device HAL) will still work after uVisor is enabled. The general use case is the following:
group-onsemi 0:098463de4c5d 352
group-onsemi 0:098463de4c5d 353 ```C
group-onsemi 0:098463de4c5d 354 #define MY_IRQ 42
group-onsemi 0:098463de4c5d 355
group-onsemi 0:098463de4c5d 356 /* Set the ISR for MY_IRQ at runtime.
group-onsemi 0:098463de4c5d 357 * Without uVisor: Relocate the interrupt vector table to SRAM and set my_isr as
group-onsemi 0:098463de4c5d 358 the ISR for MY_IRQ.
group-onsemi 0:098463de4c5d 359 * With uVisor: Register MY_IRQ for the current box with my_isr as ISR. */
group-onsemi 0:098463de4c5d 360 NVIC_SetVector(MY_IRQ, &my_isr);
group-onsemi 0:098463de4c5d 361
group-onsemi 0:098463de4c5d 362 /* Change the IRQ state. */
group-onsemi 0:098463de4c5d 363 NVIC_SetPriority(MY_IRQ, 3);
group-onsemi 0:098463de4c5d 364 NVIC_EnableIRQ(MY_IRQ);
group-onsemi 0:098463de4c5d 365 ```
group-onsemi 0:098463de4c5d 366
group-onsemi 0:098463de4c5d 367 > **Note**: In this model a call to `NVIC_SetVector` must always happen before an IRQ state is changed. In platforms that don't relocate the interrupt vector table such a call might be originally absent and must be added to work with uVisor.
group-onsemi 0:098463de4c5d 368
group-onsemi 0:098463de4c5d 369 For more information on the uVisor APIs, checkout the [uVisor API documentation](API.md) document.
group-onsemi 0:098463de4c5d 370
group-onsemi 0:098463de4c5d 371 ### The *main box* ACLs
group-onsemi 0:098463de4c5d 372
group-onsemi 0:098463de4c5d 373 The code samples that we provide in this guide give you a ready-made list of ACLs for the main box. The list includes peripherals that we already know will be necessary to make the example app work, and it is specific to the NXP FRDM-K64F target.
group-onsemi 0:098463de4c5d 374
group-onsemi 0:098463de4c5d 375 This section shows how to discover the needed ACLs for the main box. You might need to follow these instructions in case you want to generate the ACLs list for a different target or a different app.
group-onsemi 0:098463de4c5d 376
group-onsemi 0:098463de4c5d 377 At the moment the uVisor does not provide a way to detect and list all the faulting ACLs for a given platform automatically. This is a planned feature that will be released in the future.
group-onsemi 0:098463de4c5d 378
group-onsemi 0:098463de4c5d 379 In order to generate the list of ACLs, use the code provided in the [Enable uVisor](#enable-uvisor) section. In this case, though, start with an empty ACLs list:
group-onsemi 0:098463de4c5d 380
group-onsemi 0:098463de4c5d 381 ```C
group-onsemi 0:098463de4c5d 382 static const UvisorBoxAclItem g_main_box_acls[] = {
group-onsemi 0:098463de4c5d 383 }
group-onsemi 0:098463de4c5d 384 ```
group-onsemi 0:098463de4c5d 385
group-onsemi 0:098463de4c5d 386 You now need to compile your application using uVisor in debug mode. This operation requires some more advanced steps, which are described in detail in the [Debugging uVisor on mbed OS](DEBUGGING.md) document. The main idea is that you compile the application in debug mode:
group-onsemi 0:098463de4c5d 387
group-onsemi 0:098463de4c5d 388 ```bash
group-onsemi 0:098463de4c5d 389 $ mbed compile -m K64F -t GCC_ARM -o "debug-info"
group-onsemi 0:098463de4c5d 390 ```
group-onsemi 0:098463de4c5d 391
group-onsemi 0:098463de4c5d 392 and then use a GDB-compatible interface to flash the device, enable semihosting, and access the uVisor debug messages. Please read the [Debugging uVisor on mbed OS](DEBUGGING.md) document for the detailed instructions.
group-onsemi 0:098463de4c5d 393
group-onsemi 0:098463de4c5d 394 Once the uVisor debug messages are enabled, you will see you application fail. The failure is due to the first missing ACL being hit by the main box code. The message will look like:
group-onsemi 0:098463de4c5d 395
group-onsemi 0:098463de4c5d 396 ```
group-onsemi 0:098463de4c5d 397 ***********************************************************
group-onsemi 0:098463de4c5d 398 BUS FAULT
group-onsemi 0:098463de4c5d 399 ***********************************************************
group-onsemi 0:098463de4c5d 400
group-onsemi 0:098463de4c5d 401 ...
group-onsemi 0:098463de4c5d 402
group-onsemi 0:098463de4c5d 403 * MEMORY MAP
group-onsemi 0:098463de4c5d 404 Address: 0x4004800C
group-onsemi 0:098463de4c5d 405 Region/Peripheral: SIM
group-onsemi 0:098463de4c5d 406 Base address: 0x40047000
group-onsemi 0:098463de4c5d 407 End address: 0x40048060
group-onsemi 0:098463de4c5d 408
group-onsemi 0:098463de4c5d 409 ...
group-onsemi 0:098463de4c5d 410 ```
group-onsemi 0:098463de4c5d 411
group-onsemi 0:098463de4c5d 412 Now that you know which peripheral is causing the fault (the `SIM` peripheral, in this example), you can add its entry to the ACLs list:
group-onsemi 0:098463de4c5d 413
group-onsemi 0:098463de4c5d 414
group-onsemi 0:098463de4c5d 415 ```C
group-onsemi 0:098463de4c5d 416 static const UvisorBoxAclItem g_main_box_acls[] = {
group-onsemi 0:098463de4c5d 417 {SIM, sizeof(*SIM), UVISOR_TACLDEF_PERIPH},
group-onsemi 0:098463de4c5d 418 };
group-onsemi 0:098463de4c5d 419 ```
group-onsemi 0:098463de4c5d 420
group-onsemi 0:098463de4c5d 421 > **Note**: If the fault debug screen does not show the name of the peripheral, you need to look it up in the target device reference manual.
group-onsemi 0:098463de4c5d 422
group-onsemi 0:098463de4c5d 423 For readability, do not use the hard-coded addresses of your peripherals, but rather use the symbols provided by the target CMSIS module.
group-onsemi 0:098463de4c5d 424
group-onsemi 0:098463de4c5d 425 Repeat the process multiple times until all ACLs have been added to the list. When no other ACL is needed any more, the system will run without hitting a uVisor fault.