FB pixel

Renesas RA - 11. Introduction to MCUBoot using the Renesas RA Family Part 2

Published


Using MCUboot in Swap Mode

Hello again! This is the second part of the tutorial devoted to the MCUboot bootloader. In the previous part we considered what this bootloader is, created the bootloader application where MCUboot works in the Overwrite mode, started the user’s application using it, and tried to deceive MCUboot with an old version but without success. In this part we will try to use MCUboot in the Swap mode.

Creation and Configuration of the Bootloader Application in Swap Mode

We can create the new project from scratch and configure it in almost the same way as we did in the first part, except for some bootloader settings. But it’s easier to import the existing project with copying it as a new one. Let me show you how to do this.

Select the “File” in the main menu and then click on the line “Import..” (Fig. 1).

Figure 1 - Importing a project
Figure 1 - Importing a project

In the opened window select the “Rename & Import Existing C/C++ Project into Workspace” (Fig. 2).

Figure 2 - Importing and renaming the existing project
Figure 2 - Importing and renaming the existing project

Click the “Next >” button and see the next window (Fig. 3).

Figure 3 - Selecting the source project to import from
Figure 3 - Selecting the source project to import from

In the top field type the new project name. Let it be “mcuboot_swap_with_signature”. Then click the “Browse…” button near the field “Select root directory” and select the “mcuboot_overwrite_with_signature” which we have created in the first part. Then in the “Projects” field you will see this project. Select it and click the “Finish” button.

Now, in the Project Explorer you can see the new “mcuboot_swap_with_signature” project. If you open its files, you can see that it’s absolutely identical to the “mcuboot_overwrite_with_signature”. So this time we will not need to pass all these steps to reduce the bootloader application size and to change the code. The only thing we need to do here is to reconfigure the “MCUboot” stack. So open the “configuration.xml” file of the “mcuboot_swap_with_signature” project, move to the “Stacks” tab and click on the “MCUboot” block to open its properties. Then change them according to Fig. 4.

Figure 4 - Properties of the “MCUboot” stack
Figure 4 - Properties of the “MCUboot” stack

Here I highlighted the options that differ from the previous project. So we need to change the “Upgrade Mode” to “Swap” to run the MCUboot in the Swap mode. Then we disable the downgrade prevention, as it is applicable only in the Overwrite mode.

Then we change the Custom Signing Option from “--confirm” to “--pad”. As I said in the previous portion of this tutorial, if we use the “--pad” argument, the new image is not confirmed automatically, and we need to do this manually from the user’s application.

Also, we need to increase the “Bootloader Flash Area Size (Bytes)” from 0x3800 to 0x4800, and this application requires more memory. Finally, we set the “Scratch Flash Area Size (Bytes)” as 0x800, which is the minimum possible value. The Scratch area, as I mentioned in the first part, is used as an interim buffer to copy the image from the secondary slot to the primary slot.

Now we can click the “Generate Project Content” button and build the project. There should not be any errors. The code size is 16596 bytes (Fig. 5), which in the hexadecimal format is 0x40D4. That’s why we set the Bootloader Flash Area Size as 0x4800 this time.

Figure 5 - Code size of the bootloader application
Figure 5 - Code size of the bootloader application

This time we don’t need to configure the Python environment, as it has been done in the previous part, and as I mentioned, it needs to be done only once. So far that’s really all we need to do with the bootloader application. As you can see, if we import an existing project, it takes much less time to configure it. If you want to create this project from scratch, you need to go through all the steps described in the first part of this tutorial, the only difference is the “MCUboot” block configuration (Fig. 4), everything else is the same.

Let’s now create the user’s application based on the previous one.


Creation and Configuration of the User’s Application in Swap Mode

Let’s rename and import the “blinky_overwrite_with_signature” project from the previous part in the same way as we did with the bootloader application (Fig. 1, 2) and call it “blinky_swap_with_signature” (Fig. 6).

Figure 6 - Importing and renaming the user’s application project
Figure 6 - Importing and renaming the user’s application project

Even though this application only makes an LED blink, we will need to change more things in it. First we need to right click on the “blinky_swap_with_signature” project and open its properties. Then in the “C/C++ Build” list in the left parts select the “Build Variables” line, then click on the “BootloaderDataFile” variable, and click the “Edit…” button (Fig. 7).

Figure 7 - Editing of the “BootloaderDataFile” variable
Figure 7 - Editing of the “BootloaderDataFile” variable

As you remember, this variable consists of the path to the bootloader’s “.bld” file which is used for signing the application.

So we need to replace the “mcuboot_overwrite_with_signature” text in the path with the “mcuboot_swap_with_signature” to link this user’s application with the new bootloader application. Don’t forget to replace it twice - in the project name and in the “.bld” file name (Fig. 8).

Figure 8 - Changing the “BootloaderDataFile” variable
Figure 8 - Changing the “BootloaderDataFile” variable

Then select the “Environment” in the left list. Here we need to edit the Environment variables. Click on the “MCUBOOT_IMAGE_SIGNING_KEY” and then click on the “Edit…” button (Fig. 9).

Figure 9 - Editing the “MCUBOOT_IMAGE_SIGNING_KEY” variable
Figure 9 - Editing the “MCUBOOT_IMAGE_SIGNING_KEY” variable

We also need to replace the “mcuboot_overwrite_with_signature” text with the “mcuboot_swap_with_signature” (Fig. 10).

Figure 10 - Changing the “MCUBOOT_IMAGE_SIGNING_KEY” variable
Figure 10 - Changing the “MCUBOOT_IMAGE_SIGNING_KEY” variable

Here we need to change it just once - in the project name. Then we click “OK”, and in the previous window select the “MCUBOOT_IMAGE_VERSION” variable. Make sure that its value is “1.0.0” like in Fig. 9. If it’s different, then edit it as well.

Now you can click the “Apply and Close” button to return to the main window of the IDE.


A Bit More Theory About the Swap Mode

Before moving forward we need to clarify some things about the MCUboot operation in Swap mode. At the initial state the application in the primary slot is running (see table 1 in the previous part). When we first download the new image to the secondary slot and run the bootloader, it checks and validates this image, and if everything is fine, swaps the primary and secondary slots.

The behavior at the next reset depends on the value of the “image_ok” byte which is the part of the so-called image trailer. The image trailer is the special area which is located after the application itself in the flash memory and contains some service information which is used by the bootloader. This image trailer is very well described here Bootloader — MCUboot 1.9.99 documentation (I don’t know why but the Nordic Semiconductor guys described MCUboot even better than the Linaro team, to which it belongs).

For now we just need to know that there is the “image_ok” byte, and if its value in the image at the first slot is 0x01 then the image is fine, and after the reset no further swapping is required. If its value is 0xFF then the image is faulty, and we need to swap the images back. So using this variable you can control the behavior of the bootloader application and revert back the previous version of your application if the new version has some problems.

The primary image confirmation can be achieved in the new image compile time or runtime. If you set the custom signing option as “--confirmed” (Fig. 7 of the first part) then if the image is valid, the “image_ok” byte will be set automatically, and thus this is the confirmation at the compile time.

If you set the custom signing options as “--pad” (Fig. 4) then you need to add some means into the user’s application to set the “image_ok” byte, so this is the confirmation at the runtime. Let’s consider how to do this.

Open the “configuration.xml” file of the “blinky_swap_with_signature” project and switch to the “Stacks” tab. Then click on the “New Stack >”, expand the “Bootloader” list and select the “MCUboot Image Utilities” (Fig. 11).

Figure 11 - Selection of the “MCUboot Image Utilities” stack
Figure 11 - Selection of the “MCUboot Image Utilities” stack

Now we need to set the properties of the block “MCUboot Image Utilities” (Fig. 12)

Figure 12 - Properties of the “MCUboot Image Utilities” block
Figure 12 - Properties of the “MCUboot Image Utilities” block

As you can see, we need to write the locations of the three bootloader configuration files “mcuboot_config.h”, “sysflash.h”, and “mcuboot_logging.h”. All these files can be found at the “mcuboot_swap_with_signature/ra_cfg/mcu-tools/include/” folder (see the green boxes in Fig. 12). You can use the absolute path here or you can use this “../../../../” construction to locate the required files. Please note that you need to use the normal slashes in the path, not backslashes, and also you can’t use the “$workspace_loc” variable as we did when we declared the build and environment variables. Otherwise it will not find the required files and will give errors.

Then we need to click on the “Add Requires Flash”, select “New>” and “Flash (r_flash_lp)”. After that we need to configure the “g_flash0 Flash (r_flash_lp)” block in the same way as we did it in the bootloader application (Fig. 13).

Figure 13 - Configuration of the “g_flash0 Flash (r_flash_lp)” block
Figure 13 - Configuration of the “g_flash0 Flash (r_flash_lp)” block

Now we can click on the “Generate Project Content” button and build the project. If you did everything correctly, there will not be any errors. Please make sure that there is the “blinky_swap_with_signature.bin.signed” file in the “Debug” folder (Fig. 14).

Figure 14 - The image file has been created
Figure 14 - The image file has been created

Now, as both applications are ready, let’s run the project.


Downloading the Initial User’s Application

The same as before, open the “Debug Configurations…” (Fig. 15).

Figure 15 - Opening the “Debug Configurations…”
Figure 15 - Opening the “Debug Configurations…”

In the opened window make sure that you configure the “blinky_swap_with_signature_Debug_Flat” in the left list then switch to the “Startup” tab, click on the second image and then change it by clicking the “Edit…” button (Fig. 16).

Figure 16 - Edition of the bootloader image location
Figure 16 - Edition of the bootloader image location

In the opened window replace the “mcuboot_overwrite_with_signature” with the “mcuboot_swap_with_signature” both in project name and file name (Fig. 17).

Figure 17 - New bootloader application location
Figure 17 - New bootloader application location

Click “OK” to return to the previous window, and then click “Debug” there. Make sure that we stopped at the Reset_Handler of the “mcuboot_swap_with_signature” project (Fig. 18).

Figure 18 - Starting at the “mcuboot_swap_with_signature” project
Figure 18 - Starting at the “mcuboot_swap_with_signature” project

Now, that the same as the previous time, click at the “Load Ancillary File” button and select the “${workspace_loc:\blinky_swap_with_signature\Debug\blinky_swap_with_signature.bin.signed}” file. Also please change the address to 0x4800 because, as you remember, (see Fig. 4), this bootloader application has the size 0x4800 bytes (Fig. 19).

Figure 19 - Loading the user’s application to the primary slot
Figure 19 - Loading the user’s application to the primary slot

Click “OK” to download the user’s application to the primary slot. Then press the “Resume” button twice to run the bootloader. If you did everything correctly, you should see the slow flashing of the LED.

Let’s now see the memory regions of the primary and secondary slots. Please note that this time they start at addresses 0x4800 and 0x9800, respectively (Fig. 20, 21).

Figure 21 - Content of the primary slot after the first startup
Figure 21 - Content of the primary slot after the first startup
Figure 22 - Content of the secondary slot after the first startup
Figure 22 - Content of the secondary slot after the first startup

So in the primary slot there is the correct application, and in the secondary slot there is some garbage because, in the Swap mode, MCUboot doesn’t erase it if there is no valid image.

This is the initial program setup, let’s now change the user’s application and download it into the secondary slot.

Let’s open the “hal_entry.c” file of the “blinky_swap_with_signature” project and change the value of the freq_in_hz variable from 2 to 8 in line 48.

Also, as I mentioned before, we need to add some code to confirm the image after swapping. To do this, we need to expand the “Developer Assistant” of the current project, then consequently expand “HAL/Common”, “MCUboot Image Utilities”, and “Quick Setup”. There you will see two points: “Confirm Primary Image” and “Pending Secondary Image”. We need to drag and drop the first point to the “hal_entry.c” file right before the main loop which starts in line 65 (Fig. 23).

Figure 23 - Changes in the “hal_entry.c” file
Figure 23 - Changes in the “hal_entry.c” file

So, as follows from their titles, “Confirm Primary Image” confirms the primary image and thus prevents swapping the images at the next reset, while “Pending Secondary Image” makes the bootloader rollback the secondary image into the primary slot. As you can see, everything is quite simple.

Now let’s build the project and open the “Debug Configurations…” once again. Once the bootloader and the primary application are already in the flash memory there is no need to download them every time. So switch to the “Startup” tab and for the bootloader image also select “Symbols only”. Also you can uncheck the checkbox “Set breakpoint at: main”, this will prevent double clicking the “Resume” button (Fig. 24).

Figure 24 - Changes in the debug configuration
Figure 24 - Changes in the debug configuration

Now you can click the “Debug” button and see that we are still at the same Reset_Handler of the bootloader. Click on the “Load Ancillary File” button and load the secondary application to its slot (address 0x9800, Fig. 25).

Figure 25 - Loading the secondary application
Figure 25 - Loading the secondary application

Click the “OK” button and then check the memory content of the primary and the secondary slots again (Fig. 26, 27).

Figure 26 - Content of the primary slot after loading the secondary application
Figure 26 - Content of the primary slot after loading the secondary application
Figure 27 - Content of the secondary slot after loading the secondary application
Figure 27 - Content of the secondary slot after loading the secondary application

There are no surprises here. The primary slot content is the same as it was initially (compare Fig. 21 and Fig. 26), and the secondary slot now contains the new application. Let’s now click the “Resume” button to let the bootloader do its business.

After some time you should see that the LED is flashing very fast. This means that the new image was validated, swapped with the old image, and now running.

Let’s now see the flash content of the primary (Fig. 28) and secondary (Fig. 29) slots.

Figure 28 - Content of the primary slot after swapping
Figure 28 - Content of the primary slot after swapping
Figure 29 - Content of the secondary slot after swapping
Figure 29 - Content of the secondary slot after swapping

If you now compare the content of the slots before (Fig. 26-27) and after swapping (Fig. 28-19), you may notice that it has been truly swapped. So the bootloader works as desired.

Let’s now try to change the confirmation setting of the user’s application and see how this will affect the bootloader operation.

Let’s open the “hal_entry.c” file again and discard all the changes in it. Then let’s drag and drop the “Pending Secondary Image” from the Developer Assistant to line 64 (Fig. 30).

Figure 30 - Changes in the “hal_entry.c” file
Figure 30 - Changes in the “hal_entry.c” file

Now we can build the application. The debug configuration is set up correctly after the last changes so we can click on the “Debug” button at once. Then we download the new application to the secondary slot in the same way as in Fig. 25, and click “Resume” to run the bootloader.

After a few seconds you should see that the LED blinks slowly again which means that the new application has been swapped with the old one and now is running. Now let’s click on the “Reset” button on the development board to reset the MCU. In a few seconds the LED begins to blink fast again, which means that the applications were swapped again, and now the old one is running. That happened because in the new application we didn’t confirm the primary application, so the bootloader rolled it back. If you press the reset button again, the LED will still blink fast because the old application has the confirmation code, and thus no swapping is pending.

That’s actually all I wanted to tell you about the operation of the MCUboot in the Swap mode. As you see, from some perspectives, it is more convenient than the Overwrite mode due to the rollback ability. So you can load the new application and add to it the code to return to the previous version if something goes wrong.

In the next part we will consider the last supported mode - Direct XIP.

As homework, try to change the code of the bootloader and the user’s application to perform the code confirmation at the compile time by changing the custom signing option from “--pad” to “--confirm” the same as we did in the Overwrite mode.



Make Bread with our CircuitBread Toaster!

Get the latest tools and tutorials, fresh from the toaster.

What are you looking for?