Let's create a Secure Bootloader application from scratch to test the Secure booting feature on PIC32CM LS60 MCU.
Step 1.1: Setup MPLAB® X IDE MCC Plugin
1
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.
2
In MPLAB X, 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.
Step 1.2: Create a Secure Bootloader Project
The following steps explain the Secure Bootloader project creation.
Step 1.2.1: 32-bit MCC Harmony Project
Step 1.2.2: Harmony Installation Path
Step 1.2.3: Project Name and Location
1
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 MPLABX 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 'bootloader_pic32cm_ls60_cpro' to set the project's name.
Note: The Path box is read-only. It will update as you make changes to the entries.
- Click Next to proceed to Configuration Settings.
Step 1.2.4: Project Configuration Name and Target Device
1
Give a name for the configuration, pic32cm_ls60_cpro could be used.
2
The device used in the project is PIC32CM5164LS60100.
3
Copy the device name and paste it to the Device Filter to have the Target Device properly selected.
4
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.
- secure_boot/firmware/secure_bootloader/NonSecure/firmware/pic32cm_ls60_cpro_NonSecure.X
- secure_boot/firmware/secure_bootloader/Secure/firmware/pic32cm_ls60_cpro_Secure.X
Step 1.3: MCC Content Manager Wizard
Step 1.3.1: Framework selection
Step 1.3.2: Required Content
1
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.
Step 1.3.3: Optional Content
1
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:
Step 1.3.4: Download the Content
Step 1.3.5: Open MCC Project
2
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.
4
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.
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.
Step 1.4: Configure the Secure Bootloader Project using MCC
Now you can start configuring the components needed for this application.
Step 1.4.1: Project Graph View Management
1
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.
2
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.
Step 1.4.2: Configure Bootloader Component
1
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.
Step 1.4.3: UART Bootloader Configuration
3
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.
5
Select the UART Bootloader block and perform the following configurations. The bootloader size is 4KB.
UART Bootloader Configurations:
- Configure the Bootloader size as 4KB i.e., 4096 bytes.
- Enable the Bootloader trigger from firmware. This option can be used to force trigger the bootloader from application firmware after a soft reset.
- 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.
- Enable Fuse Programming as the Fuse programming is done by the Bootloader.
- And, Enable Watchdog Refresh If Enabled Through FUSE
Step 1.4.4: SERCOM2 Configuration
1
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.
- 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.
- Configure the Receive Pinout as SERCOM PAD[1] as shown in the figure.
Step 1.4.5: Boot Fuse Configuration
1
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.
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.
Step 1.4.6: Clock Configurations
2
The Clock Easy View window will then appear on your screen.
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.
- 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.
- 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.
- 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.
Step 1.4.7: Trustzone Memory Configuration
1
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.
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.
- The Application Secure, Data Secure, and Boot Protection size granularity is 256 bytes.
- The RAM Secure size granularity is 128 bytes.
3
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.
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.
Note:
- The above steps explain the usage of the TrustZone plugin. Hence do not make the above memory configurations in your application.
Step 1.4.8: TrustZone Peripheral Configuration
1
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.
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.
Note:
- The above steps explain the usage of the TrustZone plugin. Hence do not configure other peripherals except the ones shown above.
Step 1.4.9: Pin Configuration
2
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
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.
Step 1.4.10: Generate Code
Step 1.4.11: Post Build Configuration
1
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.
Step 1.4.12: 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:
1
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 MPLAB Code Configurator (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.
Note: The NVMCTRL_Initialize, PORT_Initialize, PM_Initialize, CLOCK_Initialize, EVSYS_Initialize, NVIC_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.
2
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;
}
3
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;
}
4
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;
}
5
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!
Step 1.4.13: Build the Secure Bootloader Project
1
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.
Table of Contents
|