Understanding Bit-Band Operations in STM32 Microcontrollers

This issue’s topic:
The SRAM of STM32 microcontrollers has two regions that support bit-band operations. So, what is bit-banding? How does bit-band operation work?
Today, I will sort out the knowledge points in this area.

Let’s talk about:

Before introducing bit-band operations, let’s first look at the memory mapping of the ARM Cortex-M3.

The address space of CM3 is 4GB, and programs can execute in the code area, internal SRAM area, and external RAM area.

The program memory, data memory, registers, and input/output ports of STM32 microcontrollers are organized within the same 4GB linear address space. Data bytes are stored in memory in little-endian format.

Understanding Bit-Band Operations in STM32 Microcontrollers

CM3 uses the following terminology to represent addresses related to bit-band storage:

  • Bit-band region: The address region that supports bit-band operations

  • Bit-band alias: Access to the alias address will eventually convert to access to the bit-band region (Note: There is an address mapping process)

The Cortex-M3 memory map includes two bit-band regions. These two bit-band regions map each word in the alias memory region to a bit in the bit-band memory region, writing a word in the alias storage has the same effect as executing a “read-modify-write” operation on the target bit in the bit-band region.

The two bit-band regions are:

  • The first is the lowest 1MB range of the SRAM region, with an address range of 0x2000_0000-0x200F_FFFF
  • The second is the lowest 1MB range of the on-chip peripheral region, with an address range of 0x4000_0000-0x400F_FFFF

In addition to being used like ordinary RAM, the addresses in these two bit-band regions also have their own “bit-band alias regions,” which expand each bit into a 32-bit word. When you access these words through the bit-band alias regions, you can achieve the goal of accessing the original bits.

The correspondence between the bit-band region and the bit-band alias region is shown in the figure below:

Understanding Bit-Band Operations in STM32 Microcontrollers

In the bit-band region, each bit is mapped to a word at an alias address, which is a word where only the LSB is valid. When an alias address is accessed, it is first converted to the bit-band address.

In STM32F10xxx, peripheral registers and SRAM are both mapped to a bit-band region, allowing single-bit read and write operations.

The following mapping formula shows how each word in the alias region corresponds to the respective bit in the bit-band region:

bit_word_addr = bit_band_base + (byte_offset × 32) + (bit_number × 4)
Where:
  • bit_word_addr is the address of the word in the alias memory region, which maps to a target bit
  • bit_band_base is the starting address of the alias region
  • byte_offset is the index of the byte containing the target bit in the bit-band
  • bit_number is the position of the target bit (0-31)

For example, how to map the bit 2 of the byte in the SRAM address 0x20000300 in the alias region.

0x22006008 = 0x22000000 + (0x300 × 32) + (2 × 4)

The write operation to address 0x22006008 has the same effect as executing a “read-modify-write” operation on bit 2 of the byte at SRAM address 0x20000300.

Advantages of Bit-Band Operations:
If there were no bit-band operations, the process for accessing memory would be as follows:
  • For read operations, first read a word from the bit-band address, then right shift the needed bit to the LSB, and return the LSB.
  • For write operations, shift the bit to be written to the corresponding bit position, and then perform an atomic “read-modify-write.”
With bit-band operations, reading/writing to the bit-band alias region can complete the above operations.
The advantages of bit-band operations are most easily thought of in controlling each LED’s on and off through GPIO pins, which also greatly facilitates the operation of serial interface devices.
Bit-band operations are most useful for hardware I/O intensive low-level programs. For system programs that use bit flags extensively, the bit-band mechanism is also a great boon.
Bit-band operations can also simplify jump conditions. When the jump condition is based on a bit, previously it had to be done like this:
  • Read the entire register

  • Mask out the unnecessary bits

  • Compare and jump
Now it only requires:
  • Read the status bit from the bit-band alias region

  • Compare and jump
Another important benefit of bit-band operations is that in multitasking, it is used to implement “mutex” access to shared resources between tasks. Shared resources in multitasking must satisfy that only one task accesses it at a time, which is called an “atomic operation.”
Shared resources in multitasking must satisfy that only one task accesses it at a time (the so-called “atomic operation”).
The previous “read-modify-write” needed 3 instructions, leaving two gaps that could be interrupted, which could lead to the chaotic situation shown in the figure below:
Understanding Bit-Band Operations in STM32 Microcontrollers
By using the bit-band operations of CM3, the chaotic situation in the above example can be eliminated. CM3 makes the “read-modify-write” an atomic operation supported at the hardware level, which cannot be interrupted.
Bit-band operations in C:
The C compiler does not directly support bit-band operations. For example, the C compiler does not know that the same memory can be accessed using different addresses, nor does it know that access to the bit-band alias region is only effective for the LSB.
The simplest way to use bit-band operations in C is to #define an address for the bit-band alias region.
#define DEVICE_REG0       ((volatile unsigned long *) (0x40000000))
#define DEVICE_REG0_BIT0  ((volatile unsigned long *) (0x42000000))
#define DEVICE_REG0_BIT1  ((volatile unsigned long *) (0x42000004))
We can establish a macro that converts “bit-band address + bit number” into an alias address, and then create a macro that converts the alias address into a pointer type:
// Macro to convert “bit-band address + bit number” to alias address
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2))

// Convert the address to a pointer
#define MEM_ADDR(addr) *((volatile unsigned long *) (addr))
It is important to note that, when using the bit-band feature, the variables to be accessed must be defined as volatile. Because the C compiler does not know that the same bit can have two addresses.

Therefore, it is necessary to use volatile, so that the compiler writes the new value to memory every time, rather than optimizing and using a register to operate on a copy of the data, and only writing back the copy at the end — this can lead to inconsistent results when accessing the same bit in different ways.

In conclusion:

In the actual development of STM32 microcontrollers, it is generally recommended to use the standard library or HAL library, and we can directly use the APIs provided by the library to complete the corresponding tasks, which means the library helps us complete the bit-band conversion.

We have mastered the principles of bit-band operations, understanding both the what and the why. If we encounter related issues, we can analyze and solve them from a theoretical perspective.

Source: Learn Embedded Together

Friendly Reminder:

Due to recent changes in WeChat public platform push rules, many readers have reported not seeing updated articles in time. According to the latest rules, it is recommended to click “Recommended Reading, Share, Collect” more often to become a regular reader.

Recommended Reading:

  • 4 years burned 17 billion, another new car force goes bankrupt!

  • Xiaomi’s first electric vehicle starts at 149,900, cost-effective!

  • Huawei adds 3 patent licensing plans! Netizens: The fees are too low

Please click 【Looking】 to give the author a thumbs up

Understanding Bit-Band Operations in STM32 Microcontrollers

Leave a Comment

×