Secure Boot on PIC32CM LS60 Curiosity Pro Evaluation Kit Using MPLAB® Harmony v3 Software Framework: Step 1

Last modified by Microchip on 2023/11/15 13:33

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.

If you do not have a Harmony dedicated folder, please create one on your computer. A suggestion would be something like C:/Microchip/Harmony/v3.

Back to top

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.

MCC setup

If you don't see it in the menu, install MCC.

Back to top

Create a Secure Bootloader Project

The following steps explain the Secure Bootloader project creation.

Back to top

32-bit MCC Harmony Project

Open MPLAB X IDE, and from the File menu, choose New Project.
Choose the 32-bit MCC Harmony Project

MCC New Project Wizard

Back to top

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.

Framework Path

Back to top

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.

New Project Name Location Next

Note: The Path box is read-only. It will update as you make changes to the entries.

Click Next to proceed to Configuration Settings.

Back to top

Project Configuration Name and Target Device

Give a name for the configuration, pic32cm_ls60_cpro could be used.

Back to top

The device used in the project is PIC32CM5164LS60100.

Back to top

Copy the device name and paste it to the Device Filter to have the Target Device properly selected.

Config Settings

Back to top

Click the Finish button.

Note: Since PIC32CM LS60 MCU has a TrustZone® module, MCC creates separate Secure and NonSecure projects.
MCC creates the following projects.

  1. secure_boot/firmware/secure_bootloader/NonSecure/firmware/pic32cm_ls60_cpro_NonSecure.X
  2. secure_boot/firmware/secure_bootloader/Secure/firmware/pic32cm_ls60_cpro_Secure.X

Back to top

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.

Content Manager

Back to top

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.

Back to top

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

Optional Content

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:

Manifest File

Back to top

Download the Content

All the necessary content, if any, should start downloading.

  • Expand them to see progress.

MCC Content Required

  • Wait for the packages to download.
  • Expand component groups to see the individual component checkout status.

Back to top

Open MCC Project

Choose the Harmony Framework Path.
When finished, two windows should appear. Click Next.

DFP Packs

Back to top

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.

Remove Secure Project

  • Set the bootloader_pic32cm_ls60_cpro_Secure as a Main Project.

Back to top

MCC Secure Bootloader Project View
Once open, the MCC project graph view is shown below.

Proect Creation Step 3

Back to top

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.

BS Project Properties

Tool Tip:
You can also open the Project Properties by selecting the project from the Projects tab and File > Project Properties from the main IDE menu.

Ensure that XC32 (v4.21) is selected as the Compiler Toolchain for XC32. Click on Apply and then click on OK.


When configuring the compiler toolchain, make sure to select the latest device PIC32CM-LS_DFP and CMSIS versions.

Tool Tip: If you closed MCC accidentally and would like to open it again, go to Tools > Embedded > MPLAB Code Configurator v5 in MPLAB X IDE.

Back to top

Configure the Secure Bootloader Project Using MCC

Now you can start configuring the components needed for this application.

Back to top

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.

Project Graph

Back to top

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.

Canvas Size

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.

Back to top

Configure Bootloader Component

The Bootloader Library is used to upgrade the firmware on a target device without the need for an external programmer or debugger.
In this training module, you will use the UART Bootloader library to develop a Secure bootloader.

Back to top

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 on the “UART Bootloader”

Back to top

Click Yes to automatically make the connections to NVMCTRL peripheral library, as shown below.

Auto connect to NVMCTRL peripheral library

Back to top

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.

SERCOM 2 Satisfier

Back to top

After satisfying the UART Bootloader dependency, the project graph looks as below.

UART Bootloader dependency

Back to top

Select the UART Bootloader block and perform the following configurations. The bootloader size is 4KB.


UART Bootloader Configurations:

  1. Configure the Bootloader size as 4KB i.e., 4096 bytes.
  2. Enable the Bootloader trigger from firmware. This option can be used to force trigger the bootloader from application firmware after a soft reset.
  3. Set the Number Of Bytes To Reserve From Start Of RAM as 16 bytes. This option adds the provided offset to the RAM Start address in the bootloader linker script. The application firmware can store some pattern in the reserved bytes region from RAM start for the bootloader to check at reset.
  4. Enable Fuse Programming as the Fuse programming is done by the Bootloader.
  5. And, Enable Watchdog Refresh If Enabled Through FUSE

Back to top

SERCOM2 Configuration

Select SERCOM2 and configure it as follows.


Note: In this lab, the SERCOM2 operating mode is configured as Blocking mode as the Bootloader is running in the polling mode.

  1. Ensure both the Receive and Transmit are enabled as they are used by the Bootloader to receive the firmware image from the Host-PC and to transmit the communication status messages to the Host-PC.
  2. Configure the Receive Pinout as SERCOM PAD[1] as shown in the figure.

Back to top

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.

BS Fuse Config

Note: The NVM Secure Region Locks value 0x6 means the Secure + Non-Secure Callable Flash for the Boot region is locked. But the Secure Data Flash region (DS region) and the Secure + NSC Flash (AS region (Secure Application region)) are not locked.

  • For more information on Secure Region Unlock Bits section in the PIC32CM LS60 Datasheet.

Back to top

Clock Configurations

Launch Clock Easy View by going to the Plugins drop-down in the Project Graph window and then selecting Clock Configuration.

Plugins Clock Config

A new window, Clock Easy View, is opened inside MCC.

Back to top

The Clock Easy View window will then appear on your screen.

Clock Easy View

Tool Tip:

  • The Clock Easy View window can be maximized by clicking the maximize button or by double-clicking on the Clock Easy View window, as shown below.

Mx Button

  • After maximizing the Clock Easy View window, you can switch between the windows by clicking the drop-down icon on the right-most side of the Clock Easy View tab in MCC, as shown below.

Switch between windows

  • The Clock Easy View window can be floated by clicking the float button on the Clock Easy View window, as shown below.


  • The Clock Easy View window can be docked by clicking the dock button on the Clock Easy View window, as shown below.

Maximize Dock

  • These tips apply to all other plug-in managers like Pin Configuration, DMA Configuration, Event System Configuration, Arm® TrustZone for ARMv8-M, and NVIC Configuration.

Back to top

Verify the 16 MHz Internal Oscillator (OSC16M) is enabled and select the 12 MHz output in the Oscillator Controller box.

16 MHz Internal Oscillator (OSC16M) is enabled and select the 12 MHz output in the Oscillator Controller box

Back to top

Verify the Digital Frequency Locked Loop (DFLLUP) is disabled.

Digital Frequency Locked Loop (DFLLUP) is disabled

Back to top

Verify the Digital Frequency Locked Loop (DFLL48M) is enabled.

Digital Frequency Locked Loop (DFLL48M) enabled

Back to top

Verify the Functional Digital Frequency Locked Loop is disabled.

Functional Digital Frequency Locked Loop is disabled

Verify the GCLK Generator 1 is disabled.

GCLK Generator 1 disabled

Back to top

Verify the GCLK Generator 0 is enabled.

GCLK Generator 0 enabled

Back to top

TrustZone Memory Configuration

The TrustZone Memory Configurations can be done in two ways.

  1. Go to System > Device & Project Configuration > PIC32CM5164LS60100 Device Configuration > Memory Configuration or
  2. 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.

Fuse Mem Config

Tool Tip:

  • The following shows the granularity of the different memory region sizes.
  • The Application Non-Secure Callable and Boot Non-Secure Callable size granularity is 32 bytes.

32 bytes

  • The Application Secure, Data Secure, and Boot Protection size granularity is 256 bytes.

256 bytes

  • The RAM Secure size granularity is 128 bytes.

128 bytes

Back to top

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.

Arm Trustzone for ARMv8

A new window, Arm TrustZone for Armv8-M, is opened inside MCC.

Back to top

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 Mem Config

Tool Tip:

  • You can use the mouse and click on the highlighted markers on the Flash, Data Flash, and SRAM to modify the memory region sizes as shown below.
  • Left Click using the mouse on any one of the highlighted markers and move up and down to modify the size.
  • The green color indicates that the memory region is configured as Secure.
  • The red color indicates that the memory region is configured as Non-Secure.

Graph Plugins TrustZone


  • The above steps explain the usage of the TrustZone plugin. Hence do not make the above memory configurations in your application.

Back to top

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.

TrustZone Periph Config

Tool Tip:

  • The green color indicates that the Peripheral is configured as Secure.
  • The red color indicates that the Peripheral is configured as Non-Secure.
  • You can use the mouse and left-click on any Peripherals or Mix-Secure Peripherals or System Resources to change a peripheral from Secure to Non-Secure or vice versa.


  • The above steps explain the usage of the TrustZone plugin. Hence do not configure other peripherals except the ones shown above.

Back to top

Pin Configuration

Launch Pin Configuration by going to the Plugins drop-down in the Project Graph window and then selecting Pin Configuration.

Project Graph Pin Config

A new window, Pin Settings, is opened inside MCC.

Back to top

Once the MCC Pin Settings window is opened, scroll-down to pin number PC19PC27PA22PA23, 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

Pin Configuration

In the above step, the LEDs, Switch, and UART pins are configured as per the design schematic on the PIC32CM LS60 Curiosity Pro Evaluation Kit.
For more information on pin details, refer to the PIC32CM LS60 Curiosity Pro Evaluation Kit User Guide.

Back to top

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.

MCC Generate Code

A popup will appear, wait for the operation to finish.

MCC Generating

Back to top

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:

rm -rf ${ProjectDir}/../../../../../hex/secure_bootloader && mkdir ${ProjectDir}/../../../../../hex/secure_bootloader && cp ${ProjectDir}/${ImagePath} ${ProjectDir}/../../../../../hex/secure_bootloader

Secure Project Config

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.

Additional Options

Back to top

Add Secure Bootloader Code

The Bootloader application is already partially developed and is available in the main.c file under
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.

Tip: Press the CTRL key and left click on the SYS_Initialize function. The click will open the implementation for the SYS_Initialize function as shown in the following image.

Sys Initalize

Note: The NVMCTRL_InitializePORT_InitializePM_InitializeCLOCK_InitializeEVSYS_InitializeNVIC_Initialize, and SYSTICK_TimerInitialize are system-specific initialization functions necessary to run the device. MCC adds these modules by default to the project graph and generates code. These modules will be initialized to user configurations if the user configures them explicitly.

Back to top

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; }

BTL trigger

Back to top

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; }

CTL Sys de Init

Back to top

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 ( 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; }

BTL Get Ver

Back to top

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.
  • 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.

Code 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.

Code 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.

Code LED1_Clear();

You are now ready to build the Secure Bootloader project and observe the results!

Back to top

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

Note: The TrustZone-based projects generally have lengthy path names hence the project may fail to build when trying to build from the reference_apps or the downloaded path. To overcome this build error, it is suggested to copy the project to the root directory, i.e., C:/. Then open the project in MPLAB X IDE and build.

Back to top