How I made a Custom Bootloader for SoC Firmware Over-the-Air update

Muhammed Imdaad
5 min readApr 8, 2021

The center theme of my work was to perform a firmware upgrade on STM MCUs that do not have the ability to directly access the remote firmware repository over the air. However, after interfacing a Radio Frequency (RF) module over a supported communication interface, using In-App programming, this can be achieved on such MCUs.

I made a custom bootloader for the task. The major benefit of the custom bootloader is that we always have the current application as a backup and if something goes wrong during the update process, the bootloader could be instructed to initiate a rollback. This type of dual-mode firmware update process reduces the effective area of Flash memory for application but improves the overall reliability of the system.

I believe the ideas presented here can be readily adopted for similar Embedded systems projects. Before moving on to implementation, it’s important to have background knowledge about the following things.

Hardware and Software Components

As the System on Chip, I used the STM32 Nucleo-L073RZ dev board for the development process. The ultra-low-power STM32L073xx microcontrollers have high-speed embedded memories which contain 192Kbytes of Flash program memory, 6 Kbytes of data EEPROM, and 20 Kbytes of RAM.

Embedded Firmware is a software program that typically runs on Embedded devices. It is responsible for overall Embedded Systems functioning. It is often stored on the on-chip Flash memory. The ability to upgrade the firmware over the air is the work that I did.

Flash memory is an electronic non-volatile computer memory storage medium that can be electronically reprogrammed, which stores the bootloader and the application firmware. since Flash memory is a non-volatile memory, it retains the data even after the power supply has been removed.

The bootloader is an application whose primary purpose is to allow a system software to be updated without the use of specialized hardware such as a JTAG programmer or SWD interface. In STM SoCs these can communicate over a variety of protocols such as USART, CAN, I2C, Ethernet, USB, etc. Systems with bootloaders have at least two program images coexisting on the same microcontroller and must include branch code that performs a check to see if an attempt to update software is in progress. STM32 ecosystem contains many documents regarding each method of communication for booting purposes. Just google it!

There are two programming methods to reprogram the flash memory area; In-System Programming(ISP) and In-App Programming. With ISP, the device can be re-programmed in the circuit by using specialized hardware such as JTAG or SWD interface. The re-programming process is started manually, during which the processor is halted. It requires special circuitry. IAP on the other hand allows the running application to re-program the on-chip Flash memory. With IAP, it is possible to implement applications that can be updated remotely without the need for the physical presence of a technician. IAP allows a cost-effective method to perform a software enhancement, once the system has been already shipped.

AT commands are instructions used to control a modem. In this case a GSM module. Since each command starts with“AT”, such commands, in general, are called AT+ command sets. I used a GSM module to connect to the remote server and then to download the binary firmware file using AT commands.

Design flow

In this section, I will explain the design flow that I used for the OTA functionality. Below is how I divided my task into sub-tasks as it was much easier for me to handle smaller tasks one at a time.

  1. Create a User application with a custom bootloader
  2. Interface GSM with Arduino and finalize the AT commands required
  3. Interface GSM with STM32 and receive the firmware through GSM
  4. Store the incoming firmware receiving through GSM in the OTA region
  5. After firmware verification replace the old application
  6. Error handling in OTA
  7. Optimization
  8. Implement the end-end solution

Once you divide the work into subtasks all you need to focus on is a small part of the complete workflow. So that makes things easy to handle.

The bootloader which I made specifically for L0 takes up to 28KB of flash. Considering the future improvements to the current bootloader I thought to reserve some additional spaces and fixed the size to 32KBs. STM32L0 device flash sizes range up to 192KBs. As Therefore,

  • MAXIMUM FIRMWARE SIZE = (FLASH SIZE-32KB)/2
  • For STM32L073RZ, (192–32)/2 = 80KB will be the maximum size

The way I made the bootloader it will only do the OTA when the user makes an attempt, so the user application can be configured with minimal effort. You only need to edit small sections in the project directory.

  • Adjust the flash start address and flash size in the linker script
  • Add the offset for the vector table

If you want to do the OTA without physical human intervention, then your user application and bootloader may need to be adjusted in order to do so. For example, a user application can continuously listen (within a configured timer interrupt) to a certain topic in MQTT. So once it got such a command it will raise the flag in a certain address in Flash and initiate a Software reset. Then the bootloader should check for the flag and initiate the OTA process.

I created a flow chart of the process for a visual explanation. I hope the flow chart is self explainable.

I hope you found this interesting. With this article, all I wanted was to help you to get an idea and start your custom bootloader for your requirement. As I did this as one of my intern tasks, I couldn’t share the source codes openly :( However, feel free to reach out for any questions or doubts. I will try my best to help and sort out your issues. Cheers!!!

--

--

Muhammed Imdaad

IoT Enthusiastic | Electronic & Telecommunication Engineering Undergraduate