Skip to content

This example showcases an immutable bootloader using the MDFU client library and PIC18F46Q24 microcontroller's PDID and code protection features for firmware updates via UART and host device. Compatible with PIC18-Q24 family: PIC18F56/55/46/45/26/25/24Q24

License

Notifications You must be signed in to change notification settings

microchip-pic-avr-examples/pic18f46q24-immutable-bootloader-using-mdfu-library-mplab-mcc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Microchip Technologies Inc.

Implementing an Immutable Bootloader Using PIC18F46Q24 Microcontroller

Introduction

The PIC18-Q24 family of microcontrollers is expertly designed to meet the demands of modern embedded applications, offering a robust set of features that cater to a variety of needs. This product family offers Programming and Debugging Interface Disable (PDID) feature, making the PIC18-Q24 microcontrollers particularly well-suited for applications requiring enhanced code protection and security features to meet the growing advanced security requirements for consumer Internet of Things (IoT) and numerous other applications.

Once PDID is enabled, application code and data placed in microcontroller memory are no longer accessible through the . In-Circuit Serial ProgrammingTM (ICSPTM). This irreversibly locks a microcontroller from being erased or reprogrammed through the serial programming and debugging interface (ICSP), thereby effectively configuring the microcontroller into either a one-time programmable device or a microcontroller that can only be updated through a bootloader. If a bootloader is created and added to an application, firmware updates can be accomplished via a bootloader host application. By using code protection and PDID features, the bootloader on the microcontroller is considered immutable, and it is guaranteed to always be there, as it cannot be overwritten or erased.

This code example demonstrates an immutable bootloader implementation using the PIC18F46Q24 microcontroller and the Microchip Device Firmware Update (MDFU) client library, which enables application firmware updates through a bootloader host application and the Universal Asynchronous Receiver-Transmitter (UART) interface.

Related Documentation

Description

In this code example, the PIC18F46Q24 microcontroller is used as the client device and the Power Debugger tool facilitates the interaction with the host device through the UART communication interface for application firmware upgrades. The block diagram below provides an overview of the various microcontroller peripherals utilized in this code example, highlighting the pins configured for firmware upgrades and user interfacing tasks.


Figure 1: Block Diagram

The stand-alone Data Visualizer tool facilitates user interaction by accepting inputs and transmitting them to the microcontroller via the UART interface. It also displays the requested data in its terminal window.

The bootloader firmware continuously monitors for valid user input. Depending on the input received, it executes the appropriate bootloader functionality. Users can choose from the following bootloader functions:

In-Circuit System Programming (ICSP) Enable Sequence:

  • Validate the application image

  • Jump to the application section

  • Application firmware upgrade

The bootloader firmware is programmed using the ICSP interface. Once the PDID feature is enabled, the ICSP interface is permanently disabled, preventing the microcontroller from being programmed or erased through this interface. Consequently, the application section can only be programmed via the bootloader application implemented in the code example. The PDID configuration and WRTB code protection configured for the boot section of Flash memory ensure that the bootloader remains immutable, preventing any external alterations or modifications via the ICSP interface and also safeguarding the boot section from any modifications by the CPU.

Notes:

  1. The ICSP interface can be temporarily re-enabled using an ICSP enable sequence for limited FA capabilities. It is recommended to include the ICSP enable sequence within the bootloader section.

  2. The PDID feature enables the user to permanently disable the ICSP interface. Once the PDID feature is enabled, the microcontroller becomes permanently locked from ICSP access, preventing any further interactions via this interface. Additionally, this configuration inhibits Bulk Erase operations on the microcontroller, ensuring that the device remains secure, and its programmed data is protected from unintended modifications or deletions. Refer to TB3354 - Advanced Code Security Features in 8-bit PIC Microcontrollers added under Related Documentation section. added under Related Documentation section.

  3. The PDID feature is not enabled in this code example. It is recommended to enable these protection settings during the production phase.

It is important to note that upon power-up, a Cyclic Redundancy Check (CRC) check (CRC-16-CCITT) is performed over the bootloader section before entering it. This check is compared against a pre-calculated checksum value generated using the Hexmate tool which is integrated with MPLAB X IDE. Please refer Hexmate User's Guide to change the checksum verification method. The MDFU library assists in mapping the starting location of the application section, which, along with the CRC checksum algorithm, width and memory range, is necessary for calculating the checksum of the application section.

The LEDs on the Curiosity High Pin Count (HPC) evaluation board activate and start blinking when control shifts to the application section, triggered by the user's selection of the "Jump to Application Section" option. This visual cue indicates that the application is now in operation. Additionally, the user can revert control from the application section back to the bootloader section by executing a long press on the switch connected to pin RC5. This feature provides users with the flexibility to access the bootloader for firmware updates or configuration changes and improving the overall user experience.

Refer to the Configure Project Properties section for additional information about how to add the memory range in your generated project.

This example also demonstrates:

  • How to configure the 8-Bit MDFU Client library in MCC Melody
  • How to use the pyfwimagebuilder command line interface to convert the application hex file into an application image
  • How to use the pymdfu command line interface to update the application firmware

Software Used

This application uses the MPLAB® X IDE compiler and graphical code generator to provide an easy and seamless user experience.

The following tools are used for this demo application:

Host device requirements:

Hardware Used

Hardware Setup

The PIC18F46Q24 DIP sample on the HPC development board provides a reliable development platform. The power debugger facilitates communication with the host application via the UART interface to receive the new application image file.


Figure 5: Hardware Setup

Pin Connections

The table below shows the necessary connections between the PIC18F46Q24 MCU and the Power Debugger using jumper wires.

Signal Description MCU Pin Power Debugger Pin Description HPC Board Pin Details
LED1 RA4 - RA4 Visual indicator
LED2 RA5 - RA5 Visual indicator
LED3 RA6 - RA6 Visual indicator
LED4 RA7 - RA7 Visual indicator
Switch1 RB4 - RB4 Application to Bootloader Entry with key press at Reset
Switch2 RC5 - RC5 Application to Bootloader Entry with a long key press
UART1(TX) RC0 - On-board TX For transmitting debug messages, outputs
UART1(RX) RC1 - On-board RX For receiving user inputs
UART2(TX) RB5 CDC TX - Used for application firmware upgrade
UART2(RX) RB6 CDC RX - Used for application firmware upgrade
VDD VDD REF - Power source
Ground Ground Ground - Common ground

Firmware Flow

The application firmware is developed for the PIC18F46Q24 microcontroller using MCC Melody and MPLAB X IDE. This firmware operates on the PIC18F46Q24 microcontroller mounted on the Curiosity High Pin Count (HPC) development board. It utilizes several microcontroller peripherals, including UART, Timer, Non-Volatile Memory (NVM), the CRC module and the bootloader library, to implement the required functions of the code example. These peripherals are set up during the peripheral initialization phase and remain stable throughout run time, requiring no further configuration changes.

The 8-bit MDFU client library is configured by setting the application start address in memory and enabling the pin indicator and pin entry to indicate the execution section. The library also utilizes the NVM and UART2 peripherals for accessing memory and performing application firmware updates. The CRC module is utilized to verify the integrity of the bootloader section during initialization and to validate the application firmware during the firmware upgrade process. Timer0 (TMR0) is utilized to set a time-out for the firmware upgrade process. The UART1 instance is configured to handle user interface tasks, such as displaying menus and accepting user input, using the on-board debugger of HPC. User-provided input defines the functionality to be implemented. The below figure shows the firmware flow of the code example.


Figure 6: Firmware Flowchart

Project Properties Configuration

1. Bootloader Project Configurations

Memory Model: This option is used to configure the linker settings based on the application's start address. In this code example, the application begins at 0x8000, so the value will range from 0x0000 to 0x7FFF. Right click the project in the Projects tab and open the Project properties. Go to XC8 Global Option>XC8 Linker>Memory Model>ROM ranges.


Figure 7: Memory Model Image

Checksum Settings: This setting is necessary to compute the CRC for the bootloader section and store it at the end of the bootloader Flash region. Add the settings which include the memory range, checksum width, algorithm, and location for saving the checksum value. Refer to the XC8 compiler guide for more information about the format.

The following command calculates the CRC16-CCITT checksum for the bootloader region (address range: 0x0000 to 0x7FFD):

0000-7FFD@7FFE,offset=0x0000,algorithm=5,width=-2,polynomial=0x1021,revword=2

Navigate to Project Properties>XC8 Linker>Additional options. Enter the algorithm information into the Checksum box.


Figure 8: Checksum Settings Image

2. Application Project Configurations

Fill Flash Memory: Select the sequence as 0xFFFF and add the memory address range as 0x8000:0xFFFF.

Go to File>Project Properties. Add the below settings to the to XC8 Linker>Fill Flash Memory. These steps enable the mentioned constant to fill all the unused memory space in the generated hex file. Set the Memory address range to 0x(Application Start Address):0x(End of Flash Memory).


Figure 9: Fill Flash Memory Image

Additional Option: Set codeoffset to 8000 (start of application location). Add the settings which include the memory range, checksum width, algorithm, and location for saving the checksum value. Refer to the XC8 compiler guide for more information about the format.


Figure 10: Additional Option Image

Note: To change the verification method, refer to the Use case Examples section in Getting Started with MPLAB® Code Configurator Melody 8-Bit MDFU Client Library.

Tip: To optimize memory usage, users can build the bootloader code to determine the memory consumed by the bootloader section. Based on this information, they can adjust the starting address of the application section in the MDFU library, accordingly.

Microcontroller Peripheral Configuration for Bootloader Project

Peripherals Configuration Usage
Clock Control Clock source: HFINTOSC
HF Internal Clock: 64 MHz
Clock Divider: 1
Active Clock Tuning Update: Enabled
System clock
Configuration Bits BBSIZE: 16384
WRTB: EN
ICSPDIS: EN
Used to configure the boot section and disable the ICSP interface
Note: The ICSPDIS and WRTB settings are not implemented in the provided code example. It is recommended to use these settings during the production phase.
UART1 Requested Baud Rate: 9600
Redirect printf to UART: Enabled
Enable Transmit: Enabled
Enable Receive: Enabled
Used for user interfacing tasks and displaying output and debug messages
UART2 Requested Baud Rate: 9600
Redirect printf to UART: Enabled
Enable Transmit: Enabled
Enable Receive: Enabled
Used for firmware upgrade via the host device
NVM Generate Flash APIs: Enabled
Generate EEPROM APIs: Enabled
Generate Device ID APIs: Enabled
Used for storage of execution status in EEPROM, as well as the Application code
Timer0 Timer 0: 16bit Mode
Clock Prescaler: 1:512
Postscaler: 1:1
Clock Source: MFINTOSC (500kHz)
Requested Period: 67 secs
Used for configuring time-out
CRCSCAN Enable CRC: Enabled
Use Pre-defined Polynomial: Enabled
Pre-defined Polynomial: CRC-16-CCITT
Seed: 0x0000
Augmented Mode: Data augmented with 0 s
Enable Scanner: Enabled
Scanner Memory Region: PFM
Scanner Memory Mode: Burst
Used for performing checksum on boot section to verify with pre-defined checksum value
8-bit MDFU Client Library (Bootloader Library) Communication Protocol: UART
Application Start Address: 0x8000
Device ID: 0x7900 (automatically added)
I/O Pin Indicator: Enabled
I/O Pin Entry: Enabled
Memory Verification: Checksum
Used for configuring the application start address and selecting the memory verification scheme

Demo Operation

Application Operation

  1. Open the application project and build with the latest version of the tools specified in the Software Tools section.
  2. Build the application image file using pyfwimagebuilder command
  • To build the application image files, navigate to the Projects tab and right click Important Files>build_free_image.bat for Windows or Important Files>build_free_image.sh for Mac and Linux
  • Select Run and observe the Run Successful message on the output window.


Figure 11: Executing the pyfwimagebuilder Command

Command example:

pyfmimagebuilder build -i "application_hex_file.hex" -c "bootloader_configuration.toml" -o output.img


Figure 12: pyfwimagebuilder Command Success

  1. Open the Data Visualizer and initiate the COM port linked to the HPC on-board debugger to display messages for user interaction.
  2. Use the pymdfu command to transfer the application image file to the bootloader. Ensure that the user selects the application image download option on the client side through their input.
  • To run the update with the examples, navigate to the Project tab and right click Important Files>pymdfu_update.bat for Windows or Important Files>pymdfu_update.sh for Mac and Linux. Double click to open the file.
  • Edit the port number to the CDC port name assigned to the Power Debugger
  • Then right click the script and select Run


Figure 13: Executing the pymdfu command

Command Example:
pymdfu update --tool serial --image ./application.img --baudrate 9600 --port COM##


Figure 14: pymdfu command success

Client Operation

  1. The demo requires user input to perform its defined functionalities. Users can select their input to enable the corresponding functionalities, as illustrated in the firmware flowchart.
  2. Connect the hardware as illustrated in the Hardware Setup. Power on the Curiosity HPC board and the Power Debugger using the micro-USB cable.
  3. Download the firmware from the provided MPLAB Discover link.
  4. Build the project using the latest version of the tools specified in the Software Tools section and load the generated hexadecimal file onto the PIC18F46Q24 microcontroller.
  5. After running the program, observe the default screen displayed in the image below


Figure 15: Bootloader Menu Display

  1. Enter 'A' to see the output displayed as shown below.


Figure 16: ICSP Enable Sequence Execution

  1. Enter 'B' to see the output displayed as shown below.


Figure 17: Download Image Execution

Note: Use the pymdfu command to transfer the application image file to the bootloader, as mentioned in the Application Operation section.

  1. Enter 'C' to see the output displayed.


Figure 18: Jump to Application Execution


Figure 19: Jump to Application Failure

  1. Enter 'D' to see the output displayed as shown below.


Figure 20: Application Image Verification


Figure 21: Application Image Verification Failure

  1. Enter anything other than the provided inputs to see the output displayed as shown below.


Figure 22: Invalid Input Display

  1. In addition to the bootloader execution, if a long press is detected while the system is in the application section, control will be transferred to the bootloader section.


Figure 23: Bootloader Entry Screen

Note: The input provided by the user is case sensitive, so only uppercase inputs are accepted as valid inputs.

Conclusion

This code example demonstrates the implementation of an immutable bootloader by using the code protection and PDID features of the PIC18-Q24 microcontroller family. Additionally, it explains how to set up the 8-Bit MDFU Client library in MCC to enable device firmware updates on the PIC18F46Q24 microcontroller via a bootloader host implementation. The integration of PDID and code protection features within the microcontroller improves on-chip security, ensuring the secure protection and storage of user configuration data and application code in the memory.

About

This example showcases an immutable bootloader using the MDFU client library and PIC18F46Q24 microcontroller's PDID and code protection features for firmware updates via UART and host device. Compatible with PIC18-Q24 family: PIC18F56/55/46/45/26/25/24Q24

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages