STM32 Firmware Update Over the Air (FOTA) – Bootloader Part 6

This article is a continuation of the Series on STM32 Bootloader and carries the discussion on Bootloader design and implementation. The aim of this series is to provide easy and practical examples that anyone can understand. This post is STM32 Firmware Update Over the Air (FOTA) – Bootloader Tutorial Part 6 where we will do STM32 Wireless Firmware Update.

We have attached the video explanation also at the bottom of this post.


In this STM32 Wireless Firmware Update example, we will be using the concepts which have been explained already in the below-given tutorials. So I would request you to go through those tutorials first if you are not familiar with those topics.

We are providing the video format of this Bootloader series. Please check out the video playlist. You can also get the source code of this tutorial from GitHub.

Hardware Required

STM32 Firmware Update Over the Air

What did we do in our previous tutorial?

Previously, the STM32 Nucleo board is connected with the desktop or laptop using the USB to serial converter. So, both are communicating through the cable. The firmware or application was sitting in the computer.

The firmware or application is parsed using the PC application which has been developed previously. If we want to update the firmware, then we will press the user boot button when the bootloader starts. Now the bootloader will be waiting for the data over the UART.

The PC application sends the data to the STM32 by following our protocol. Bootloader writes the received data to either slot 0 or slot 1. After that, the bootloader copies the data from the slot to the application area and boots it. This is how we are updating our firmware or application with wire.

Let’s consider this scenario. When you deploy your product into the field, do you like to connect the computer and STM32 board then flash the firmware every time? No right. You may like it, but I never like this process. Because I don’t want to touch the hardware every time. To avoid that, can we update the firmware without wire? Yes. We will see how to do that in this tutorial.

Concept of this tutorial

In this tutorial, I have connected the STM32 board and BT-05 Bluetooth board. You can use any Bluetooth chip like ESP32, HM10 Module, etc which supports BLE. These BT-05 pins are connected to STM32’s USART 2 pins. The BT-05 gives you the received Bluetooth data via UART to the STM32.

The mobile application is connected to the BT-05 via Bluetooth. When the chip power-up, the bootloader gives controls to the application that blinks the LED. When the OTA is available, We don’t have to press the reset button and user boot button.

The mobile app will inform the BT-05 via BLE. We have developed the android application for this purpose. Then the Bluetooth module sends that data to the STM32 via USART 2. Then the application gives the control to the Bootloader. So, that bootloader can start the OTA process. Then the mobile application sends the firmware package data to the STM32 Bootloader via Bluetooth. And it writes data to slot 0 or slot 1. Then it copies the data to the application area and runs the new application.

In this tutorial, I won’t touch the Bootloader. So, it will remain the same as our previous tutorial (0.3 version).

Add the OTA feature to the Application

Now we will add the OTA feature to the Application so that, it will give control to the Bootloader when Firmware OTA is available. I am enabling the USART 2. So, make the PD6 as RX and PD5 as TX in the Blinky.ioc file. Please refer to this video for a better understanding.


#include "etx_ota_update.h"

#define MAJOR 0   //APP Major version Number
#define MINOR 4   //APP Minor version Number

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  if (huart->Instance == USART2)
    if( !strncmp("ota", (char*)rx_buf, 3) )
      printf("Received OTA Request from Mobile Application\r\n");

      /* Update the reboot reason as OTA request */

      /* Read the configuration */
      ETX_GNRL_CFG_ cfg;
      memcpy( &cfg, (ETX_GNRL_CFG_*) (ETX_CONFIG_FLASH_ADDR), sizeof(ETX_GNRL_CFG_) );

      //update the reboot reason
      cfg.reboot_cause = ETX_OTA_REQUEST;

      /* write back the updated config */
      write_cfg_to_flash( &cfg );

      // Reset the controller
      HAL_UART_Receive_IT(&huart2, rx_buf, 3);
    memset(rx_buf, 0, sizeof(rx_buf));

int main(void)
  HAL_UART_Receive_IT(&huart2, rx_buf, 3);

I have added (modified) the above code to the application which has been created by the previous tutorial.

Code Explanation

We will have to receive the UART data asynchronously. So, I am using the interrupt method instead of polling. I have added the HAL_UART_Receive_IT() function which tells to receive the 3 bytes data from the USART2.

Whenever we receive the 3 bytes, this HAL_UART_RxCpltCallback() function will be called. There we will have to check that we received data from USART2. If so, check that we have received the string “ota“. The android app will send the string “ota” to STM32’s application to start the OTA process.

Then the application changes the reboot cause as OTA Request and writes it to the flash.

After that, it resets the controller. Now the bootloader will take care of the OTA process. If we didn’t receive the string “ota“, then we again schedule the Rx.

Now when the bootloader starts, it will read the reboot cause as OTA Request. So, it will wait for the OTA data.

Build the Application and Flash it to the STM32 using our previous tutorial’s steps.

After the flashing, See, the 0.4 application is running.

Now, this app supports OTA. Let’s verify this OTA update.

STM32 OTA Example

Connection diagram

I have connected the BT-05 to STM32’s USART 2. Please check the connection using the below image.

And I have changed the baudrate of the BT-05 to 115200 bits using the AT command “baud 8“. The default baud rate is 9600.

Let’s create a new application to verify the OTA process.

Create new application

I have added a new Red LED blinking feature to the application. Please check this video to see how I have added the Red LED.

Build the new application and copy it to the Mobile Phone.

Android Application

We have developed a simple android application using flutter to demonstrate this OTA update. You can get the android application source code from GitHub.

I have just simply learned the flutter in a few days and wrote this app. So, this android app is a very basic app and it may have many bugs. Even if you click the cancel button during the transmission, it won’t react. Because I am running a for loop which makes the UI hang. I don’t know the proper way to handle this. If you are able to fix this problem, please give us the solution. And also, we are not taking care of the response that STM32 sends for each chunk. You can add that too if you are able to fix that.

STM32 Firmware Update Over the Air (FOTA) – Demo

Open the Flashy App. Connect to BT05. There are many characteristics available. I am going to use the last custom characteristic for our communication. Select write. Then select the binary file which we want to flash. Then start the OTA process. Please check the video for reference.

This OTA process took almost 18 minutes. Yes, I agree. For just a 20Kb file, it is taking that much time. It is huge. We can optimize it. I am leaving this optimization to you.

See, the new application has been flashed successfully. New app 0.5 is running now. And see the LEDs. Both Blue and Red LEDs are blinking.


That’s it. We have flashed the new application over the air (STM32 Firmware Update Over the Air). Let’s celebrate it.

You can get the all source code from GitHub.

Video Explanation


You can also read the below tutorials.

Linux Device Driver TutorialsC Programming Tutorials
FreeRTOS TutorialsNuttX RTOS Tutorials
RTX RTOS TutorialsInterrupts Basics
I2C Protocol – Part 1 (Basics)I2C Protocol – Part 2 (Advanced Topics)
STM32 TutorialsLPC2148 (ARM7) Tutorials
PIC16F877A Tutorials8051 Tutorials
Unit Testing in C TutorialsESP32-IDF Tutorials
Raspberry Pi TutorialsEmbedded Interview Topics
Reset Sequence in ARM Cortex-M4BLE Basics
VIC and NVIC in ARMSPI – Serial Peripheral Interface Protocol
Bootloader TutorialsRaspberry PI Pico Tutorials
5 1 vote
Article Rating
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x