4.1 AVR128DA48 Bootloader Example

Basic bootloader example using the UART driver interface with both XC8 and GCC compiler steps.

Summary

This section details a full standard bootloader use case on the AVR128DA48 microcontroller. This example applies to many variants of the AVRDA family and may also be extrapolated to other 8-bit AVR chips as well. This example uses the AVR128DA48 Curiosity Nano Board purchased from Microchip. Visit the device schematics for configuration information.

Example

This example shows how to bootload a program that blinks the LED of the AVRDA family of chips.

Create a New Project

Click the New Project icon in the top left of the menu.

Select Standalone

Select Standalone Project and click Next.

Setup Target Device

An AVR128DA48 is used for this example. Type the name of the device into the Device field and MPLAB® X IDE will display the options.

Select a tool for programming. The AVR128DA48 Curiosity Nano Board will be used for this example as well. Select the tool from the drop down and then click Next.

Note: If only ‘Simulator’ is displayed, then the target board is not plugged into the computer or it is not communicating with MPLAB® X IDE properly.

Select a Compiler

In this example XC8 compiler v2.40 is used. A GCC compiler may also be used. To do this, select a GCC compiler version from the AVR-GCC drop down tab in this menu. Click Next after selecting the compiler.

Project Name

Type the desired project name into the Project Name field. Then click Next. Give it a descriptive name so the project can be easily identified.

Activate MCC

Click on the MCC button in the menu bar to start the Code Configurator.

Click on the new MCC Melody button for this example.

Use the Optional Content tab to install optional libraries (such as the bootloader). If no other libraries need to be installed, click Finish.

Attach the 8-bit Bootloader Library

In the past versions of MCC a user needed to attach all peripheral drivers required by their library manually, using the Device Resources window. The new MCC Melody allows users to select the library needed for the project. Melody brings in all the dependencies and configures them.

Confirm that the bootloader module has been included into the Builder window. Builder UI should reflect all the required peripheral driver dependencies such as Memory or NVM module, the UART module, and the timer Delay module and link them to the Bootloader library.

Attach the UART Driver

One of the modules that cannot be configured automatically is the communication driver. In order for the bootloader to communicate with the Bootloader Host Application, a communication driver needs to be exposed that pushes data through the serial ports on the target device. To understand which communication ports are required to be opened for the device in use check the schematics and look for the Serial or CDC Ports definition for the device, as shown in the image below. Using this definition, the MCU is communicating through port PC0 for transmitting data serially and port PC1 for receiving data serially.

A communication driver version that communicates through the PC0 and PC1 ports is needed. For workflows on the AVR128DA48 CNano, USART1 driver needs to be attached because that is the UART driver that can communicate through those ports. To configure the desired UART version, open the UART(None) tab and select the version from the selector.

Note: Some devices will automatically select the required UART pins. Open the Pin Grid View to make sure the pins are enabled.

Configure I/O Pins

There are several advantages of configuring I/O pins for a bootloader, but the most important one is receiving a state back from the MCU based on the LED. For example, the bootloader module will light up the LED when in a Boot state and it will turn off when the application state takes over. The program flow is now tracked during the development process. Telling the Bootloader module to utilize the I/O Indicator pin sets up the functionality. This is done by clicking on the switch that activates the I/O Pin Indicator. For this example, the I/O Entry Pin will also be configured. This pin is used to force the MCU into a Bootloader state by checking for voltage levels on the entry pin at any device reset. To activate this pin select the UI switch from the bootloader tab.

Check the schematics to configure the I/O pin for using the LED on the board. In the schematics there is an I/O interface declaration, similar to the image below. For the AVR128DA48, PC6 port needs to be connected to control the LED.

Go back to MPLAB® X IDE and navigate to the Pin Grid View in the bottom center of the screen.

Select the PC6 pin for the BOOT INDICATE in the pin grid and PC7 for the BOOT ENTRY pin.

Note: For further configuration, access the Pins Module UI through: Project Resources > System > Pins

Address the Notifications in the Notifications [MCC] tab

The bootloader supports the configuration process. Address all the notifications shown in the Notifications tab.

For example, NVM options must be enabled. Addressing the notification will either turn it into a hint or remove it from the list.

Initial Generation and Programming

Click on the Generate button in the Project Resources tab to generate the initial code.

Note: This step will generate a warning on the screen. Continue the set-up process.

Program the Device

Identify how much memory the generated code uses before configuring the bootloader memory block. To do that, use MPLAB® X IDE to program the bootloader onto the target device. MPLAB® X IDE displays a log after the initial programming . The log shows the memory addresses occupied by the bootloader program. Configure the bootloader’s FUSE values based on the log. Click Clean and Build and then Program Device.

Calculate FUSE Ranges

As seen in the image above, the bootloader code is taking up memory from 0x0 to 0x5ff. The Boot section of memory needs to be configured at a minimum 0x600 in size to fit the bootloader code. The range must be pushed slightly higher to account for the RAM needed during operation. In this example, extra space is added to the bootloader to mimic a production design choice suitable for several solutions. There can also be a design where extra space is added to the Boot section to house an internal library within the Boot section of Flash.

Note: Adding extra space in the Boot section of Flash is a design decision that must be considered on an as needed basis.

Memory Map

8-bit AVR devices utilize the FUSE settings to partition the device memory into various sections needed to support bootloading operations. Below is the configuration description for configuring the FUSE settings in a manner that reflects user needs. A bootloader requires at least two of the three sections of memory (BOOT and APPCODE) and therefore users must set a non-zero value for the Boot bit in every bootloader they implement. The Code bit can be configured if needed but it is not required.

Note: An omitted fuse byte will be set to 0x00 and will most likely cause an unpredicted configuration
The memory range needed for the bootloader (0x600) and the extra space added (0xA00) takes the Boot space to a total memory size of 0x1000. Plug the 0x1000 into the equation mentioned below.
Note: A programming calculator must be used not a standard one, considering this equation uses hexadecimal not decimal numbers.

The Boot Fuse value is now 0x08.

FUSE Configurations

The Fuse values can be configured in two ways for the operation of the bootloader. First, configure the size of the Boot section of memory and then allow the compiler to handle everything. To gain more control over the various portions of memory set a Boot section size and an AppCode size which will automatically create a third section called AppData.

Note: Remember that the Boot section of Flash cannot be overwritten by the sections below it.

The fuse values define the size of each of these respective sections using the calculations in the figures above. For example,select a Boot fuse value of 0x08 and a Code fuse of 0x00 then from the mathematics above the Boot section of Flash will be partitioned from address 0x00 to 0x1000, of memory and the AppCode section will be the rest. When selecting a Boot fuse of 0x08 and a Code fuse of 0x09, the Boot section goes from 0x00 to 0x1000, the AppCode section will go from address 0x1000 to 0x1200, and the AppData will take up the rest of Flash. Use the chart below as a reference when designing device fuse settings.

Set the FUSE values in Bootloader

Take the Bootsize Fuse calculated in the last step and plug it into the Fuse UI field within the Configuration Bits tab. Click the Configuration Bits module in the Project Resources tab. Then input the value calculated into the respective field.

Setting the CODESIZE fuse is an optional action that can be done in instances where a user want more control over the various portions of memory. If this value is set to 0x00 the bootloader will still operate normally but it is not possible to specify an AppData section of memory without first configuring the Codesize fuse. For more information on how to configure this option refer to the memory map presented in the Fuse portion of this document.

Regenerate Code

The new code files can now be generated for the bootloader once more. After generation is complete click Clean & Build to compile the bootloader code.

Blinking LED End Application Project

Now that the bootloader code is built and configured to specifications, configure the target application to work alongside the bootloader instead of erasing the bootloader code from the device and programming the new target application over it. MPLAB® X IDE allows this by setting various project configuration properties to match the bootloader’s configuration. The first step for completing this task is to create a Blinking LED Project.

Create another new Standalone project, name it something notable and set it as the main project in MPLAB® X IDE.

Create an Offset Configuration

One important part of the development process to follow is the idea of creating multiple configurations for the target application. This allows users to create various application images that can be used for different purposes at the same time and the bootloader uses this concept extensively.

For this example two configurations are neeeded, one that is the default configuration and one that is the Offset configuration. The Offset will be needed in order to program the bootloader and the end application onto the same chip. Start by navigating up to the configuration drop down and click Customize ....

From here click on the Manage Configurations ... button at the bottom left of the Project Properties window.

Duplicate the default configuration by clicking Duplicate. Then select Rename and type in “Offset”, and click OK.

Lastly, set the Offset configuration as the Active configuration for the project. Click the Set Active button while the Offset configuration is highlighted blue. Once the Offset has been set as the active configuration, close this window.

Set LED pin in Application

Next open MCC to configure the LED for the blinking light application. Click the MCC icon in the menu bar to start the MPLAB® Code Configurator.

Set PC6 as the LED pin and provide a custom name for the LED. Click on generate code to generate the project code.

Attach the DELAY module

The delay timer can be found in the Device Resources by unfolding the tabs Drivers > Timer > Delay

Write the blinking light logic

Generate the code as is. Then open the main.c file and add the following logic.

#include "mcc_generated_files/system/system.h"
#include "mcc_generated_files/timer/delay.h"
/*
    Main application
*/

int main(void)
{
    SYSTEM_Initialize();


    while(1)
    {
        DELAY_milliseconds(500);
        LED0_Toggle();
    }    
}

Set the Linker Options

These next steps are dependent on the compiler used in MPLAB® X IDE and the steps will change slightly due to that. For both XC8 and GCC compilers specify where the text memory range of the end application starts. This setting is required in order for the compiler to program the end application into the correct range of memory and prevent overwriting the bootloader code.

XC8

Navigate to the Project Properties > XC8 Linker .

Then, using the drop down menu navigate to Additional Options.

In the Extra Linker Options text box, double click and type the following options into the text box. Click OK when finished.
Note: For XC8, the 0x1000 in this linker option was taken directly from the bootloader Fuse configuration. Length of the Boot Space is passed so the linker knows where to write the end application code.
-Wl,-Ttext=0x1000

AVR GCC

There is a slight difference in steps to be followed between the GCC compiler and the XC8 compiler. The process starts the same, navigate to Project Properties > avr-ld. Then select Memory Settings from the drop down.

Then simply use the mathematics described for setting the text range in XC8 but using the GCC linker option format. For GCC type the following line into the FLASH segment text box.

Note: This value is in words. Therefore the value set in the bootloader (0x1000) must be divided by 0x2 to get this value of 0x800.
.text=0x800

Clean and Build Project

Clean & Build the Offset configuration for the Blinking light application. This is the application image used for bootloading.

Program the Bootloader

Now to prepare the chip for a bootloaing process, set the bootloader project as the Main Project then click Make and Program Device. After this programming process ends, LED on the AVR128DA48 will illuminate and stay lit up.

Open and Configure the UBHA

Open up the Unified Bootloader Host Application and then click Open File. Make sure to open the <application-MPLABX-project/dist/Offset/production/application Hex file>.

Next select the type of architecture for the example used i.e. AVR128D family.

Next configure the COM port number to pass the command strings from the UBHA to the bootloader. Select Settings > Serial and then configure the COM port from the given options. To find the COM port in Windows, hit the Windows key and type Device Manager. Once the device manager has started, open the Ports tab and look for a Virtual COM Port. That port will be used to bootload an application with the UBHA.

Start Bootloading Task

Before beginning the programming process with the UBHA, open the Console of the app where the logs that are returned from the bootloader will displayed. Click on Tools > Console and click the Program Device button to begin the bootloading process.

Configuring the AVR Post Build Steps

By utilizing a post build step, it is possible to perform analysis and prep the application image in ways that a normal compiler cannot do. This section discusses how to configure a post build script for AVR applications and how to create the CRC32 verification ready image from the blinking light application. For more information refer to CRC Verification Scheme section.

Start by creating a new file in the blinking light application folder by opening the Files tab. Right click on the project folder and select New > Other

Select Shell Scripts > Bourne Shell Script (.sh)

Name the new script and click Finish.

Post Build Script

Many things can be done using Hexmate with the application image but for this example, a general post build script for the bootloader applications that can be used to prepare an application for any of the hashed verification schemes supported will be explained. User can also use this script as a reference to write a new Hexmate script in the future. Copy the script here into the newly created .sh script file and save it.
Note: This script is developed using a BOOT FUSE value of 0x08. Ex: 0x08 * 0x200 = 0x1000
REM Fill Unimplemented Flash Space with 0xFF
hexmate r0-FFFFFFFF,%2 -O%2 -FILL=w1:0xFF@0x1000:0x1FFFF

if %1 == CRC16 REM Calculate CRC-16 and store at footer
if %1 == CRC16 hexmate %2 -O%2 +-CK=1000-1FFFD@1FFFE+FFFFg5w-2p1021

if %1 == CRC32 REM Calculate CRC-32 and store at footer
if %1 == CRC32 hexmate %2 -O%2 +-CK=1000-1FFFB@1FFFC+FFFFFFFFg-5w-4p04C11DB7

if %1 == CHECKSUM REM Calculate Checksum and store at footer
if %1 == CHECKSUM hexmate %2 -O%2 +-CK=1000-1FFFD@1FFFEg2w-2

Create the Batch Script

If Windows machine is used, create this exact same script but as a .bat file instead. To do this copy and paste a new copy of the script file just created in MPLAB X.

Right click on the new copy of the script and select Properties

Rename the file back to the original name from the copy and then set the extension to bat.

Create the new configurations

The last step to configuring the post build script is to create a new project configuration that can run the script with the required inputs for Hexmate. Open the project properties of the application project and create a copy of the Offset configuration. Rename it to CRC32 and then populate the Building settings with:
postBuildStep${ShExtension} CRC32 ${ImagePath}
Note: To utilize this script for any of the verification schemes, replace the CRC32 with either CRC16 or CHECKSUM in the command seen above.

Build CRC32

Clean and Build the application. Hexmate commands can be seen running in the output window after the initial compilation succeeded.

Also by opening the CRC32 configuration .hex file, the last spaces in the image file being filled with some data can be seen.