Secure Boot on PIC32CM LS60 Curiosity Pro Evaluation Kit Using MPLAB® Harmony v3 Software Framework: Step 2
Contents
- Create a Test Application Project
- MCC Content Manager Wizard
- Configure the Test Application project Using MCC
- Project Graph View Management
- PIC32CM LS60 Curiosity Pro BSP Configuration
- Fuse Configuration
- SysTick Configuration
- SERCOM3 and STDIO Configurations
- Harmony Core Configuration
- Clock Configurations
- TrustZone Memory Configuration
- TrustZone Peripheral Configuration
- Pin Configuration
- Generate Code
- Post Build Configuration
- Add Test Application Code
- Build the Test Application Project
Let's create a test application from scratch to test the Secure booting feature.
- Once the test application is successfully loaded by the Secure Bootloader, a message will be printed in the Virtual COM, indicating that it was loaded from the Secure Bootloader, and the LED1 (Red-LED) will toggle. If SW0 is pressed and held, it will trigger the Secure Bootloader to program the application again with a new application. The following steps will show how to configure the components for the application and generate the code.
Create a Test Application Project
The following steps explain the test application project creation.
32-bit MCC Harmony Project
Open MPLAB® X IDE. From the File menu, choose New Project. Choose the 32-bit MCC Harmony Project.
If you don't see it in the menu, install MCC.
Harmony Installation Path
The path to your Harmony 3 installation folder should already be populated.
If not, create a folder somewhere on your computer, like C:/Microchip/Harmony/v3, and point the project to that path.
The necessary Harmony 3 files will be downloaded to that path later in these steps.
Project Name and Location
In the Project Settings window, apply the following settings:
- Location: Indicates the path to the root folder of the new project. All project files will be placed inside this folder. The project location can be any valid path, for example, C:/secure_boot/firmware/test_app.
- Folder: Indicates the name of the MPLAB X IDE .X folder. Enter "pic32cm_ls60_cpro" to create a pic32cm_ls60_cpro.X folder.
- Name: Indicates the name of the project that will be shown in MPLAB X IDE. Enter "app_pic32cm_ls60_cpro" to set the project's name.
Click Next to proceed to Configuration Settings.
Project Configuration Name and Target Device
Copy the device name and paste it to the Device Filter to have the Target Device properly selected.
Click the Finish button.
MCC Content Manager Wizard
Framework Selection
After the project has been created for MPLAB X IDE, MCC will automatically start, asking for the Framework to use.
Press Select MPLAB Harmony.
Required Content
The Content Manager Wizard will start by automatically adding the required content to be downloaded.
If the Harmony Framework is not downloaded yet on the user's computer, the required content should show the following packages to download:
- bsp
- csp
- core
- dev_packs
- quick_docs
If the Framework is already present, then the required content could be empty or some updates available.
Optional Content
If any content is needed for this application, it must be downloaded now using the Wizard. If the Harmony packages are installed, they will not appear in this list.
Usually, the application should work when using the latest available packages.
The list of the versions the latest built was tested with is available in the project. Each time when the project is generated successfully using Harmony, a file called harmony-manifest-success.yml is also created in the src/config/<config_name>/ folder, where the versions used for the tools are listed.
The following figure is the content of the .yml file created when the project was created:
Click on Finish to start downloading the content and have the MCC project created.
Open the MCC Project
Choose the Harmony Framework path.
When finished, two windows will appear. Click Next.
MCC Project View
Once open, the MCC Project Graph view appears as shown in the following figure.
Configure the Test Application project Using MCC
Now you can start configuring the components needed for the test application.
Project Graph View Management
It's crucial to maintain a neat Project Graph, so make sure to organize the components as you add them. The order of arranging components in the Project Graph is from right to left, starting from peripherals, followed by drivers, stack, and application.
To expand the space available in the Project Graph, click on the blue window button located in the Project Graph Toolbar.
To allow for more space at the bottom, it may be necessary to adjust the layout of the Project Graph. This is important because the right side is reserved for the Component Settings, and hiding components under it by mistake can cause problems.
If the width is set to 800 and the height to 1280, click OK. The Project Graph will provide more space for adding components and a vertical scroll bar will appear to navigate the added components. It is important to note that the right side of the window is reserved for the Component Settings, which should not be accidentally hidden under the added components.
PIC32CM LS60 Curiosity Pro BSP Configuration
To add the board BSP, click on the PIC32CM LS60 Curiosity Pro BSP under Device Resources > Libraries > Harmony > Board Support Packages (BSPs) > PIC32CM LS60 Curiosity Pro BSP. This configures the onboard Switches and LEDs. i.e., SW0, SW1, LED0, and LED1.
After the successful addition of BSP, the Project Graph appears as shown.
Fuse Configuration
As the Secure Bootloader updates the fuse configurations, the generation of fuse configurations has been disabled in the test application project. The User Row configurations, including the application's memory configurations and User NVM Rows, can be updated by the application. To update the fuse configurations while programming the application, the btl_host.py script will use the pre-generated application_user_configurations_out.txt configuration file, which is based on the test application's memory configurations. The following is the memory configuration diagram for the test application.
SysTick Configuration
SysTick is enabled and a 1-second delay is added in the test application for the UART Console to get enumerated after reset.
SERCOM3 and STDIO Configurations
To configure the STDIO, click on Device Resources > Libraries > Harmony > Tools > STDIO.
After the addition of the STDIO, the Project Graph looks as follows.
Now connect SERCOM3 with the STDIO interface to print log messages.
- Right-Click the red diamond in STDIO, click on Satisifiers and choose SERCOM3.
- Now you can see that the SERCOM3 is connected to STDIO.
Select SERCOM3 and configure it as follows.
Harmony Core Configuration
To configure the Harmony Core, click on Device Resources > Libraries > Harmony > Core > Core.
After the addition of the Harmony Core, a pop-up comes asking whether FreeRTOS™ needs to be activated.
- Click No as you are not using the FreeRTOS in this project.
Finally, the Project Graph looks as follows.
Now select the Core component and perform the following configurations.
- Enable the checkbox to Generate Harmony Application Files.
Clock Configurations
Launch Clock Easy View by going to the Plugins drop-down in the Project Graph MCC window and then selecting Clock Configuration.
A new window, Clock Easy View, is opened inside MCC.
The Clock Easy View window will then appear on your screen.
Verify the 16 MHz Internal Oscillator (OSC16M) is enabled and select the 12 MHz output in the Oscillator Controller box.
Verify the Digital Frequency Locked Loop (DFLLUP) is disabled.
Verify the Digital Frequency Locked Loop (DFLL48M) is enabled.
Verify the Functional Digital Frequency Locked Loop is disabled.
Verify the GCLK Generator 1 is disabled.
Verify the GCLK Generator 0 is enabled.
TrustZone Memory Configuration
The TrustZone Memory Configurations can be done in two ways.
- Go to System > Device & Project Configuration > PIC32CM5164LS60100 Device Configuration > Memory Configuration or
- Launch Arm TrustZone for Armv8-M by going to the Plugins drop-down in the Project Graph window and then selecting Arm TrustZone for Armv8-M.
- The Test Application is configured to use both Secure and Non-Secure memory regions.
- The flash memory configurations for the test application are shown in the following figure.
- The 512 KB flash is divided into three regions, i.e., Secure Boot, Secure, and Non-Secure Application regions.
- Secure Boot region is already allocated to the Secure Bootloader project.
- Secure Boot Protection size is configured as 4 KB, i.e., 4096 bytes.
- The Test Application project uses the Secure and Non-Secure memory regions.
- The Secure Application size is configured as 16 KB, i.e., 16384 bytes.
- The remaining available memory is 512KB-4KB-16KB (492 KB), i.e., 503808 bytes configured as Non-Secure Application size.
- The Non-Secure region is not present; hence the sizes for Application Non-Secure Callable and Boot Non-Secure Callable are set to 0 bytes.
Note: Ensure the entire DATA and SRAM flash is configured as Secure.
- Data Secure size is 16 KB, i.e., 16384 bytes.
- Secure RAM is divided into two regions, Secure and Non-Secure regions.
- The Secure RAM size is 16 KB, i.e., 16384 bytes configured for the Secure region.
- The remaining size is 48 KB, i.e., 49512 bytes is configured for the Non-Secure region.
Launch Arm TrustZone for Armv8-M by going to the Plugins drop-down in the Project Graph window and then selecting Arm TrustZone for Armv8-M.
A new window, Arm TrustZone for Armv8-M, is opened inside MCC.
Open the TrustZone Manager plugin under Plugins to view or modify the Memory Configurations in a graphical view.
TrustZone Peripheral Configuration
To view the peripheral configurations, you can click on the Peripheral Configuration tab in the TrustZone Manager plugin. All peripherals are set to Secure mode by default, except for the DSU.
- In this test application, SERCOM3 is configured as a Non-Secure peripheral. It will be used to print log messages when the test application firmware is loaded by the Secure Bootloader.
- To configure the SERCOM3 as Non-Secure, click on Peripheral Configuration tab in the TrustZone Manager plugin and left-click on SERCOM3 using the mouse.
- This makes the SERCOM3 a Non-Secure peripheral.
Pin Configuration
Launch Pin Configuration by going to the Plugins drop-down in the Project Graph window and then selecting Pin Configuration.
A new window, Pin Settings, is opened inside MCC.
Once the MCC Pin Settings window is opened, scroll down to pin numbers PB20 and PB21 and then configure these pins as follows:
- Set the Pin Number #68 as SERCOM3_PAD0:
- Pin ID: PB20
- Function: SERCOM3_PAD0
- Security Mode: NON-SECURE
- Set the Pin Number #69 as SERCOM3_PAD1:
- Pin ID: PB21
- Function: SERCOM3_PAD1
- Security Mode: NON-SECURE
Generate Code
To generate the code, click on the Generate button in the Project Resource pane. This will generate the necessary code files based on the project configuration.
A popup will appear. Wait for the operation to finish.
Post Build Configuration
Open the project properties and enable the post-build option as shown below and add the following command to copy the HEX and BIN file to the test application project path, <Your_Test_Application_Project_Path>/secure_boot/hex/test_app.
Add Test Application Code
Add the pre-developed test application code, which handles the task of printing a message on the console when it is loaded by the Secure Bootloader, and it also toggles LED0 to indicate that the application is running correctly. Compare the code in dev_files/test_app/NonSecure/firmware/src, and copy it as needed.
- The test application is already partially developed and is available in the NonSecure/firmware/src/app.c, NonSecure/firmware/src/app.h, and NonSecure/firmware/src/config/pic32cm_ls60_cpro/user.h files under the path <Your_Secure_Bootloader_Downloaded_Path>/pic32cm_ls60_cpro_secure_boot/dev_files/test_app/
NonSecure/firmware/src.
- The app.c file contains the test application logic and app.h consists of the prototypes and definitions for the test application. It also contains placeholders that you will populate with the necessary code in the next step.
- The user.h file contains user definitions of the test application project.
- Go to the pic32cm_ls60_cpro_secure_boot/dev_files/test_app/ folder and copy the pre-developed NonSecure/firmware/src/app.c, NonSecure/firmware/src/app.h, and NonSecure/firmware/src/config/pic32cm_ls60_cpro/user.h files.
- Replace (over-write) the app.c, app.h, and user.h files of your project available in <Your_Secure_Bootloader_Downloaded_Path>/pic32cm_ls60_cpro_secure_boot/firmware/test_app/NonSecure/firmware/src with the copied files.
- Open app.c in MPLAB X IDE and add the test application code by following the steps below:
Under the app.c file, in the APP_Initialize() function, start the Application Timer.
{
appData.state = APP_INIT;
APP_TIMER_START();
}
Under the app.c file, in the APP_Tasks() function add the code to print the message on the console when the Secure Bootloader loads the test application.
- Also, the test application jumps to Secure Bootloader whenever switch SW0 is pressed and restarts the device.
{
/* Check the application's current state. */
switch ( appData.state )
{
/* Application's initial state. */
case APP_INIT:
{
/* Add Delay for the UART Console to get enumerated after reset */
APP_TIMER_DelayMs(1000);
printf("\r\n\r\n####### Application loaded from Bootloader #######\r\n");
appData.state = APP_SWITCH_PRESS_WAIT;
break;
}
case APP_SWITCH_PRESS_WAIT:
{
if (SWITCH_GET() == SWITCH_PRESSED)
{
appData.state = APP_TRIGGER_BOOTLOADER;
}
APP_TIMER_DelayMs(1000);
LED_TOGGLE();
break;
}
case APP_TRIGGER_BOOTLOADER:
{
printf("\r\n####### Bootloader Triggered #######\r\n");
printf("\r\n####### Program new firmware from Bootloader #######\r\n");
// The RAM location to load the Bootloader trigger pattern is located
// in RAM secure region. Hence calling secure_bootloaderTrigger().
// Never returns as it initiates a reset after loading the trigger pattern
secure_bootloaderTrigger(BTL_TRIGGER_PATTERN);
}
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}
The test application has two projects, Secure and Non-Secure. The Non-Secure application calls the Secure APIs using the Non-Secure entry interfaces present in the nonsecure_entry.h.
- Since both the Secure and Non-Secure applications are developed by a single user, you need to add the Non-Secure entry function definition into the generated nonsecure_entry.c file.
- The pre-developed code is kept in the dev_files/test_app/Secure/firmware/src/trustZone/nonsecure_entry.c
- Replace (over-write) the nonsecure_entry.c and nonsecure_entry.h files of your project available at:
<Your_Secure_Bootloader_Downloaded_Path>/pic32cm_ls60_cpro_secure_boot/firmware/test_app/
Secure/firmware/src/trustZone/nonsecure_entry.c and
<Your_Secure_Bootloader_Downloaded_Path>/pic32cm_ls60_cpro_secure_boot/firmware/test_app/
NonSecure/firmware/src/trustZone/nonsecure_entry.h with the copied files.
- Under the nonsecure_entry.c file, the secure_bootloaderTrigger() function is used to trigger the Secure Bootloader from the test application.
#include "device.h"
#define BTL_TRIGGER_RAM_START 0x20001000U
uint32_t __attribute((address(BTL_TRIGGER_RAM_START))) ramarray[4];
static uint32_t *ramStart = (uint32_t *)ramarray;
/* Non-secure callable (entry) function */
void __attribute__((cmse_nonsecure_entry)) secure_bootloaderTrigger(uint32_t triggerPattern)
{
ramStart[0] = triggerPattern;
ramStart[1] = triggerPattern;
ramStart[2] = triggerPattern;
ramStart[3] = triggerPattern;
NVIC_SystemReset();
}
Under the nonsecure_entry.h file, replace extern int secure_add(int x, int y); interface with extern void secure_bootloaderTrigger(uint32_t triggerPattern);.
You are now ready to build the test application project and observe the results!
Build the Test Application Project
To generate the test application unified binary, you need to build the test application project in the MPLAB X IDE. Once the build process is complete, the pic32cm_ls60_cpro_NonSecure.X.production.unified.bin file will be generated in the path where you created the test application project (<Your_Test_Application_Project_Path>/secure_boot/hex/test_app, e.g., C:/secure_boot/hex/test_app).