Getting started with OpenBootloader

The Open Bootloader provides services to a host application, such as STM32CubeProgrammer, to download firmware to the target device. It uses a supported communication interface such as USART, I2C, SPI or USB. The downloaded firmware is then programmed into the required user memory area.

Users can also develop their own host software based on the protocols described in the referenced STM32 application notes. On the ST side, STM32CubeProgrammer is the official host tool that supports STM32 bootloaders.

To use Open Bootloader, a valid hardware and software connection must be established between the external host and the target STM32 device.

Since Open Bootloader supports exactly same protocol interfaces as STM32 System Bootloader, following list of documents provide details of how to use each protocol:
  • AN3155 USART protocol used in the STM32 bootloader

  • AN4221 I2C protocol used in the STM32 bootloader

  • AN4286 SPI protocol used in the STM32 bootloader

  • AN3156 USB DFU protocol used in the STM32 bootloader.

Architecture overview

To boot from Open Bootloader, a system reset must be performed and the boot mode must be configured to boot from User Flash. To exit the bootloader, either execute a Go command or perform a system reset after changing the boot options to disable booting from flash

Functional description

Common services

When the open bootloader starts, OPENBL_Init() prepares the Open Bootloader environment and initializes the selected interfaces. Then OPENBL_InterfaceDetection() scans the available protocols until one is detected. Once a protocol becomes active, OPENBL_CommandProcess() handles the command exchange between the host and the target device. Unsupported commands or error conditions produce a NACK response. When the bootloader session ends, the application and unused interfaces are de-initialized.

Before using Open Bootloader, make sure that the target STM32 board, the required debugging and programming tools, and the selected communication interface are available. The boot mode pins and board configuration must also be set according to the selected protocol.

Open Bootloader supports several communication protocols. The user must first choose the protocol that matches the hardware setup and the host interface. Each protocol uses a dedicated middleware module and may require specific pin configuration, interrupts, or peripheral settings.

Typical configuration items:

  • OpenBootloader Core Description:


The openbl_core.c file contains the kernel of the Open Bootloader middleware. It is responsible for:

  • initializing the OpenBL application

  • initializing the registered communication interfaces

  • detecting active interfaces

  • processing received commands

  • de-initializing the bootloader application and interfaces

OpenBootloader Core APIs

Function

Purpose

OPENBL_Init()

Initializes the Open Bootloader application and all registered interfaces.

OPENBL_DeInit()

De-initializes the Open Bootloader application.

OPENBL_InterfacesDeInit()

De-initializes all interfaces that were not detected.

OPENBL_InterfaceDetection()

Scans all registered interfaces and returns the detected one.

OPENBL_CommandProcess()

Reads the command opcode from the detected interface and executes the corresponding command.

openbl_user_init()

Weak user hook used to initialize application-specific resources.

openbl_user_deinit()

Weak user hook used to de-initialize application-specific resources.

OpenBootloader Common Interfaces APIs

Common interface services

The openbl_itf_common.c file contains common low-level functions shared by several Open Bootloader interface modules. These functions provide generic services such as:

  • setting the Main Stack Pointer

  • enabling and disabling interrupts

  • checking the protection status of the target device

This file does not implement a specific communication protocol. Instead, it provides shared utilities used by the interface layer. The functions defined in this module are declared as weak symbols, so they can be overridden by the user if needed. This gives flexibility for platform-specific implementations while keeping a generic default behavior.

The module is typically used by interface drivers such as I2C, USART,…

Function

Purpose

OPENBL_Common_SetMsp()

Sets the Main Stack Pointer value.

OPENBL_Common_EnableIrq()

Enables global interrupt handling.

OPENBL_Common_DisableIrq()

Disables global interrupt handling.

OPENBL_Common_GetProtectionStatus()

Returns the current protection status of the target.

I2C interface services

The openbl_itf_i2c.c file contains the hardware-specific implementation of the Open Bootloader I2C interface. It provides the low-level functions required to initialize, detect, communicate, and manage error handling over the I2C protocol.

This module is responsible for:

  • I2C interface initialization and de-initialization

  • protocol detection

  • command opcode reception

  • byte transmission and reception

  • acknowledgment and busy-state handling

  • communication timeout management

  • support for special commands

Function

Purpose

OPENBL_ITF_I2C_Init()

Initializes the I2C interface instance.

OPENBL_ITF_I2C_DeInit()

De-initializes the I2C pins and peripheral instance.

OPENBL_ITF_I2C_ProtocolDetection()

Detects whether there is activity on the I2C bus.

OPENBL_ITF_I2C_GetCommandOpcode()

Reads the command opcode from the host and validates it.

OPENBL_ITF_I2C_ReadByte()

Reads one byte from the I2C communication pipe.

OPENBL_ITF_I2C_SendByte()

Sends one byte on the I2C communication pipe.

OPENBL_ITF_I2C_WaitAddress()

Waits until the device address is matched on the bus.

OPENBL_ITF_I2C_WaitNack()

Waits until a NACK condition is detected.

OPENBL_ITF_I2C_WaitStop()

Waits until a STOP condition is detected.

OPENBL_ITF_I2C_SendAcknowledge()

Sends an ACK or NACK byte to the host.

OPENBL_ITF_I2C_SendBusyByte()

Sends the busy byte when the bootloader is busy.

OPENBL_ITF_I2C_SpecialCommandProcess()

Processes I2C special commands.

OPENBL_ITF_I2C_EnableBusyStateSending()

Enables busy-state byte transmission during flash operations.

OPENBL_ITF_I2C_DisableBusyStateSending()

Disables busy-state byte transmission.

OPENBL_I2C_CommunicationError()

Handles I2C communication errors.

openbl_user_i2c_deinit()

Weak user hook used to de-initialize user-specific I2C resources.

IWDG interface services

The iwdg_interface.c file provides the Open Bootloader interface for the Independent Watchdog (IWDG).

This module is responsible for:

  • IWDG initialization (prescaler configuration/watchdog counter reload..)

  • periodic refresh during code execution

Function

Purpose

OPENBL_IWDG_Init()

Initializes the watchdog for bootloader us

OPENBL_IWDG_Refresh()

Reloads the watchdog counter to prevent a reset.

SPI interface services

The openbl_itf_spi.c file provides the hardware-specific implementation of the Open Bootloader SPI interface.

This module is responsible for:
  • SPI peripheral initialization and de-initialization

  • SPI protocol detection

  • SPI command opcode reception

  • busy-state handling

  • acknowledge handling

  • support for special commands

Function

Purpose

OPENBL_ITF_SPI_Init()

Initializes the SPI peripheral if it is not already enabled.

OPENBL_ITF_SPI_DeInit()

De-initializes the SPI interface and user resources.

OPENBL_ITF_SPI_ProtocolDetection()

Detects SPI activity and validates the synchronization byte.

OPENBL_ITF_SPI_GetCommandOpcode()

Waits for and reads the command opcode from the host.

OPENBL_ITF_SPI_ReadByte()

Reads one byte from the SPI interface.

OPENBL_ITF_SPI_SendBusyByte()

Sends a busy byte while waiting for the next host request.

OPENBL_ITF_SPI_SendByte()

Sends one byte over the SPI interface.

OPENBL_ITF_SPI_SendAcknowledge()

Sends the acknowledge sequence and waits for host acknowledgement.

OPENBL_ITF_SPI_SetRxNotEmptyState()

Sets the SPI receive-not-empty state flag.

OPENBL_ITF_SPI_GetRxNotEmptyState()

Returns the SPI receive-not-empty state flag.

OPENBL_ITF_SPI_EnableBusyState()

Enables busy-state handling in the interface object.

OPENBL_ITF_SPI_DisableBusyState()

Disables busy-state handling in the interface object.

OPENBL_ITF_SPI_SpecialCommandProcess()

Processes SPI special commands and sends the default response.

OPENBL_user_spi_deinit()

Weak user hook used to de-initialize application-specific SPI resources.

USART interface services

The openbl_itf_usart.c file provides the hardware-specific implementation of the Open Bootloader USART interface.

This module is responsible for:

  • USART peripheral initialization and de-initialization

  • protocol detection through auto-baud synchronization

  • command opcode reception

  • acknowledgment handling

  • communication timeout management through watchdog refresh

  • support for special commands

Function

Purpose

OPENBL_ITF_USART_Init()

Configures and enables the USART peripheral if needed.

OPENBL_ITF_USART_DeInit()

De-initializes the USART interface and user resources.

OPENBL_ITF_USART_ProtocolDetection()

Detects USART activity using auto-baud synchronization.

OPENBL_ITF_USART_GetCommandOpcode()

Reads and validates the command opcode from the host.

OPENBL_ITF_USART_ReadByte()

Reads one byte from the USART interface.

OPENBL_ITF_USART_SendAcknowledge()

Sends the acknowledge byte to the host.

OPENBL_ITF_USART_SendByte()

Sends one byte over the USART interface.

OPENBL_ITF_USART_SpecialCommandProcess()

Processes USART special commands and sends the default response.

openbl_user_usart_deinit()

Weak user hook used to de-initialize application-specific USART resources.

OpenBootloader specific Interfaces APIs

Engi interface services

The openbl_itf_engibytes.c file contains the memory access routine used by the Open Bootloader to retrieve a byte from a specified Engi address.

This module is responsible for:

  • reading a byte from Engi memory

Function

Purpose

OPENBL_EB_Read()

Returns the byte stored at the given address.

Flash interface services

The openbl_itf_flash.c file provides the hardware-specific implementation of the Open Bootloader FLASH access functions.

Function

Purpose

OPENBL_FLASH_Unlock()

Unlocks the FLASH control registers for write or erase operations.

OPENBL_FLASH_Unlock_OB()

Unlocks the FLASH and option byte registers.

OPENBL_FLASH_Lock()

Locks the FLASH control registers.

OPENBL_FLASH_OB_Launch()

Launches option byte loading after modification.

OPENBL_FLASH_Read()

Reads one byte from the specified FLASH address.

OPENBL_FLASH_Write()

Programs data into FLASH memory.

OPENBL_FLASH_JumpToAddress()

Jumps to the application entry address.

OPENBL_FLASH_GetProductProtectionState()

Returns the current product read-out protection state.

OPENBL_FLASH_SetWriteProtection()

Enables or disables write protection for selected FLASH pages.

OPENBL_FLASH_MassOrBankErase()

Starts a mass erase or bank erase operation.

OPENBL_FLASH_Erase()

Erases the selected FLASH pages.

OPENBL_Enable_BusyState_Flag()

Enables FLASH busy-state signaling.

OPENBL_Disable_BusyState_Flag()

Disables FLASH busy-state signaling.

OPENBL_FLASH_IsReadyForOperation()

Checks whether the FLASH subsystem is ready for a new operation.

OPENBL_FLASH_WaitForEndOfOperation()

Waits for the current FLASH operation to complete.

OPENBL_FLASH_ErasePage()

Erases one or more FLASH pages.

OPENBL_FLASH_MassErase()

Performs a complete FLASH mass erase.

OPENBL_FLASH_EraseBank()

Erases a complete FLASH bank.

HAL_GetTick()

Returns the current system tick value in milliseconds.

Options Bytes interface services

The openbl_itf_optionbytes.c file provides the low-level access functions used by the Open Bootloader to read and program Option Bytes.

This module is responsible for:

  • option byte register unlock operations

  • option byte loading launch handling

  • option byte read access

  • option byte programming

Function

Purpose

OPENBL_OB_Unlock()

Unlocks the FLASH and Option Bytes registers.

OPENBL_OB_Launch()

Launches option byte loading after programming.

OPENBL_OB_Read()

Reads one byte from the specified Option Bytes address.

OPENBL_OB_Write()

Programs one or more Option Bytes fields.

OTP interface services

The openbl_itf_otp.c file provides the low-level access functions used by the Open Bootloader to read and program One-Time Programmable (OTP) memory.

This module is responsible for:

  • OTP byte reading

  • OTP write operation handling

Function

Purpose

OPENBL_OTP_Read()

Reads one byte from the specified OTP address.

OPENBL_OTP_Write()

Programs data into OTP memory.

RAM interface services

The openbl_itf_ram.c file provides the low-level access functions used by the Open Bootloader to read, write, and jump to RAM addresses.

Function

Purpose

OPENBL_RAM_Read()

Reads one byte from the specified RAM address.

OPENBL_RAM_Write()

Writes data into RAM memory using 32-bit aligned access.

OPENBL_RAM_JumpToAddress()

Jumps to the application entry point in RAM.

read Only interface services

The openbl_itf_read_only.c file provides the low-level read function used by the Open Bootloader to access a read-only memory area.

Function

Purpose

OPENBL_RO_Read()

Reads one byte from the specified read-only address.

System Memory access services

The openbl_itf_systemmemory.c file provides the low-level read function used by the Open Bootloader to access the STM32 System Memory area.

Function

Purpose

OPENBL_ICP_Read()

Reads one byte from the specified System Memory address.