Secure Boot on PIC32CM LS60 Curiosity Pro Evaluation Kit Using MPLAB® Harmony v3 Software Framework: Step 1
Contents
- Setup MPLAB X IDE MCC Plugin
- Create a Secure Bootloader Project
- MCC Content Manager Wizard
- Configure the Secure Bootloader Project Using MCC
- Project Graph View Management
- Configure Bootloader Component
- UART Bootloader Configuration
- SERCOM2 Configuration
- Boot Fuse Configuration
- Clock Configurations
- TrustZone Memory Configuration
- TrustZone Peripheral Configuration
- Pin Configuration
- Generate Code
- Post Build Configuration
- Add Secure Bootloader Code
- Build the Secure Bootloader Project
Let's create a Secure Bootloader application from scratch to test the Secure booting feature on PIC32CM LS60 MCU.
Setup MPLAB X IDE MCC Plugin
Before using MPLAB® Code Configurator (MCC) with Harmony, configure the plugin to point to the right installation of the Harmony Framework.
In MPLAB X IDE, open Tools > Options and go to Plugins.
Select the tab MPLAB Code Configurator and scroll to the Harmony Content path.
Browse to the folder where Harmony was/will be downloaded and check the checkbox. Always ask for Harmony Content Path when opening a project.
If you don't see it in the menu, install MCC.
Create a Secure Bootloader Project
The following steps explain the Secure Bootloader project creation.
32-bit MCC Harmony Project
Open MPLAB X IDE, and from the File menu, choose New Project.
Choose the 32-bit MCC Harmony Project
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 Harmony 3 necessary files will be downloaded to that path later during 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/secure_bootloader.
- Folder: Indicates the name of the MPLAB X IDE 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 'bootloader_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. Select MPLAB Harmony.
Required Content
The Content Manager Wizard will start by automatically adding 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 3 packages to download.
- csp
- dev_packs
- quick_docs
If the Framework is already present, then the required content could be empty or some updates available.
Optional Content
Bootloader content is needed for this application, which needs to be downloaded now using Wizard. If the Harmony packages are installed, they will not appear in this list.
Download the following package if not downloaded yet on the user’s computer.
- bootloader
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 content of the .yml file at the time the documentation is written is:
Download the Content
All the necessary content, if any, should start downloading.
- Expand them to see progress.
- Wait for the packages to download.
- Expand component groups to see the individual component checkout status.
Open MCC Project
Choose the Harmony Framework Path.
When finished, two windows should appear. Click Next.
Make bootloader_pic32cm_ls60_cpro_NonSecure project as a dummy project.
- Since the Secure bootloader does not have anything in the Non-Secure project you need to make it dummy.
- Right-click on the Loadables under the bootloader_pic32cm_ls60_cpro_NonSecure project and remove the Secure project bootloader_pic32cm_ls60_cpro_Secure to unlink and make it dummy project.
- Set the bootloader_pic32cm_ls60_cpro_Secure as a Main Project.
MCC Secure Bootloader Project View
Once open, the MCC project graph view is shown below.
Before proceeding, set up the compiler toolchain. Click on the Project Properties icon on the bootloader_pic32cm_ls60_cpro_Secure - Dashboard and go to Properties.
Ensure that XC32 (v4.21) is selected as the Compiler Toolchain for XC32. Click on Apply and then click on OK.
Configure the Secure Bootloader Project Using MCC
Now you can start configuring the components needed for this 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 icon 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 and 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.
Configure Bootloader Component
In this training module, you will use the UART Bootloader library to develop a Secure bootloader.
UART Bootloader Configuration
The Secure Bootloader uses the UART module to receive the application image from a Host-PC through the UART communication interface.
To configure, in the MCC project graph, Click on the “UART Bootloader” under Device Resources > Harmony > Bootloader to configure the UART Bootloader.
Click Yes to automatically make the connections to NVMCTRL peripheral library, as shown below.
The bootloader project uses the USB-UART to click the module to receive the application image from the Host-PC. To enable communication between the bootloader and the Host-PC through the USB-UART click, the SERCOM2 module is used. To establish this connection, the UART Bootloader dependency needs to be satisfied by connecting SERCOM2 as a satisfier. This can be done by right-clicking on the red-diamond button and selecting SERCOM2 as the satisfier, as shown below.
After satisfying the UART Bootloader dependency, the project graph looks as below.
Select the UART Bootloader block and perform the following configurations. The bootloader size is 4KB.
SERCOM2 Configuration
Select SERCOM2 and configure it as follows.
Boot Fuse Configuration
The PIC32CM LS60 MCU is set up to run in secure boot mode, using the ATECC608B-based boot protection verification method and SHA-based Non-Volatile Memory (NVM) boot configuration (BOOTOPT=5). The Secure Boot key is set to 0xABABABAB, and the secure boot region is locked. The boot fuse configurations are illustrated in the figure below.
Clock Configurations
Launch Clock Easy View by going to the Plugins drop-down in the Project Graph 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 flash memory configurations for the Secure Bootloader are illustrated in the figure below.
- The 512KB flash is divided into two regions, i.e., Secure Boot and Secure Application regions.
- Secure Boot Protection size is configured as 4KB i.e., 4096 bytes.
- The remaining available memory 508KB i.e., 520192 bytes is configured as Application Secure 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.
- Ensure the entire DATA and SRAM flash is configured as Secure. i.e.,
- Data Secure size is configured as 16KB i.e., 16384 bytes.
- Secure RAM size is configured as 64KB i.e., 65408 bytes.
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.
The Arm TrustZone for Armv8-M window will then appear on your screen. You can also use the TrustZone plugin to modify the Flash, Data, and SRAM memory region size.
TrustZone Peripheral Configuration
To view the peripheral configurations, you can click on the "Peripheral Configuration" tab in the TrustZone Manager plugin. The peripheral configurations will be displayed in a graphical view, with the Secure peripherals shown in green and the Non-Secure peripherals shown in red. All peripherals will be configured as Secure by default, except for the DSU. In this particular case, the SERCOM2 peripheral has been configured as a 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 number PC19, PC27, PA22, PA23, and PB08 and then configure these pins as shown below:
- Set the Pin Number #59 as GPIO:
- Pin ID = PC19
- Custom Name = LED0
- Function = GPIO
- Direction = Out
- Latch = High
- Security Mode = SECURE
- Set the Pin Number #85 as GPIO:
- Pin ID = PC27
- Custom Name = LED1
- Function = GPIO
- Direction = Out
- Latch = High
- Security Mode = SECURE
- Set the Pin Number #72 as SERCOM2_PAD0:
- Pin ID = PA22
- Function = SERCOM2_PAD0
- Pull Up = Yes
- Security Mode = SECURE
- Set the Pin Number #73 as SERCOM2_PAD1:
- Pin ID = PA23
- Function = SERCOM2_PAD1
- Pull Up = Yes
- Security Mode = SECURE
- Set the Pin Number #15 as GPIO:
- Pin ID = PB08
- Custom Name = BOOT_PIN
- Function = GPIO
- Direction = In
- Pull Up = Yes
- Security Mode = SECURE
Generate Code
To generate the code, click on the Generate button on the top bar of MPLAB X IDE. This will generate the necessary code files based on the project configuration. Click on the Generate button in the Project Resource Window.
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 file to the Secure Bootloader project path:
<Your_Secure_Bootloader_Project_Path>/secure_boot/hex/secure_bootloader
rm -rf ${ProjectDir}/../../../../../hex/secure_bootloader && mkdir ${ProjectDir}/../../../../../hex/secure_bootloader && cp ${ProjectDir}/${ImagePath} ${ProjectDir}/../../../../../hex/secure_bootloader
The Non-Secure project is a dummy project which does not consist of any application code except that the project configuration file i.e., bootloader_pic32cm_ls60_cpro_NonSecure.mc3 is used to open the Secure project in MCC. Hence remove the additional options to stop building the Secure Gateway library (used for switching from Non-secure to Secure state) as it is not required.
Add Secure Bootloader Code
The Bootloader application is already partially developed and is available in the main.c file under
<Your_Secure_Bootloader_Downloaded_Path>/pic32cm_ls60_cpro_secure_boot/dev_files/secure_bootloader/Secure/firmware/src.
The main.c file contains the Bootloader application logic. It also contains placeholders that you will populate with the necessary code in the next step.
- Go to the pic32cm_ls60_cpro_secure_boot/dev_files/secure_bootloader/Secure/firmware/src folder and copy the pre-developed main.c file.
- Replace (over-write) the main.c file of your project available at <Your_Secure_Bootloader_Project_Path>/secure_boot/firmware/secure_bootloader/Secure/firmware/src with the copied file.
- Open main.c in MPLAB X IDE and add the application code by following the steps below:
Under the main.c file, in the main() function, notice the call to the SYS_Initialize function. The generated SYS_Initialize function initializes all the peripheral modules used in the Bootloader application, configured through MCC.
In the initialization.c file, when the SYS_Initialize() is called after the PORT_Initialize the device checks for Bootloader trigger pattern in the first 16 Bytes of RAM to enter Bootloader. If this returns false then the device starts executing the Test Application which resides at the address 0x1000UL else continues the device initialization and waits for the Test Application to be sent via USB-UART.
In the main.c file, above the main() function call, add the following code which checks for the Bootloader trigger pattern in the first 16 Bytes of RAM to enter Bootloader.
bool bootloader_Trigger(void) { /* Check for Bootloader Trigger Pattern in first 16 Bytes of RAM to enter * Bootloader. */ if (BTL_TRIGGER_PATTERN == ramStart[0] && BTL_TRIGGER_PATTERN == ramStart[1] && BTL_TRIGGER_PATTERN == ramStart[2] && BTL_TRIGGER_PATTERN == ramStart[3]) { ramStart[0] = 0; return true; } /* Check for BOOT Pin to enter Bootloader */ if (BOOT_PIN_Get() == 0) { return true; } return false; }
In the initialization.c file, when the SYS_Initialize is called by the main() function, if the bootloader_Trigger() returns false, that means a valid application is residing in the flash. In this scenario, before executing the Test Application, the Bootloader invokes the SYS_DeInitialize() function call to free any resources acquired by Bootloader.
In the main.c file, above the bootloader_Trigger() function call, add the following code which frees if any resources are acquired by the Bootloader.
void SYS_DeInitialize( void *data ) { // De-Initialize Assigned UART, I2C and Boot Pins. PORT_REGS->GROUP[0].PORT_OUT = 0x0; PORT_REGS->GROUP[0].PORT_PINCFG[22] = 0x0; PORT_REGS->GROUP[0].PORT_PINCFG[23] = 0x0; PORT_REGS->GROUP[0].PORT_PMUX[11] = 0x0; PORT_SEC_REGS->GROUP[1].PORT_OUT = 0x0; PORT_SEC_REGS->GROUP[1].PORT_PINCFG[2] = 0x0; PORT_SEC_REGS->GROUP[1].PORT_PINCFG[3] = 0x0; PORT_SEC_REGS->GROUP[1].PORT_PINCFG[8] = 0x0; PORT_SEC_REGS->GROUP[1].PORT_PMUX[1] = 0x0; }
In the main.c file, the Bootloader MAJOR_VERSION is set to 3 and MINOR_VERSION is set to 0. The Bootloader version details will be sent to the Host-PC during the communication between the Device and the Host-PC using host Python™ script (btl_host.py). More details on the host script are given in the Bootloader Scripts.
uint16_t bootloader_GetVersion( void ) { uint16_t btlVersion = (((MAJOR_VERSION & 0xFF) << 8) | (MINOR_VERSION & 0xFF)); return btlVersion; }
Let's add the code to update the status of the Bootloader and the application receiving status from the Host-PC.
- When LED0 turns ON it means the Secure Bootloader is running else not running.
- When LED1 toggles it means the Secure Bootloader is communicating with the Host-PC to receive the Test Application's firmware image.
- Under the main.c file, add LED0_Set() and LED1_Set() after SYS_Initialize function call to turn OFF the LEDs after initialization.
LED0_Set(); LED1_Set();
- Under the main.c file, add LED0_Clear() after bootloader_UART_Tasks() function call to turn ON the LED0, which indicates that the Secure Bootloader is running.
LED0_Clear();
- Under the config/pic32cm_ls60_cpro/bootloader/bootloader_uart.c file, add LED1_Set() above flash_task() function call in the function bootloader_UART_Tasks() to turn OFF the LED1.
LED1_Set();
- Under the config/pic32cm_ls60_cpro/bootloader/bootloader_uart.c file, add LED1_Clear() after input_data = SERCOM2_USART_ReadByte(); in the function input_task() to turn ON the LED1.
LED1_Clear();
You are now ready to build the Secure Bootloader project and observe the results!
Build the Secure Bootloader Project
To generate the Secure Bootloader hex file, you need to build the Secure Bootloader project in MPLAB X IDE. Once the build process is complete, the pic32cm_ls60_cpro_Secure.X.production.hex file will be generated in the path where you have created the Secure Bootloader project.
<Your_Secure_Bootloader_Project_Path>/secure_boot/hex/secure_bootloader path.
i.e., c:/secure_boot/hex/secure_bootloader