How to Use Bit Banding in ARM Cortex-M: Syntax and Examples
Bit banding in ARM Cortex-M allows you to access individual bits in memory as if they were separate 32-bit words using
bit-band alias addresses. You calculate the alias address with a formula based on the bit's byte address and bit number, then read or write to that alias to manipulate the bit atomically.Syntax
Bit banding uses a special alias region in memory where each bit in a byte region maps to a 32-bit word. The formula to get the alias address is:
bit_word_addr = bit_band_base + (byte_offset * 32) + (bit_number * 4)
Where:
- bit_band_base is the start address of the bit-band alias region.
- byte_offset is the byte offset of the target bit from the bit-band region base.
- bit_number is the bit position (0-7) within the byte.
Writing 1 or 0 to bit_word_addr sets or clears the bit atomically.
c
/* Define bit-band regions for SRAM and Peripheral */ #define BITBAND_SRAM_REF 0x20000000 #define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_PERI_REF 0x40000000 #define BITBAND_PERI_BASE 0x42000000 /* Macro to calculate bit-band alias address for SRAM */ #define BITBAND_SRAM(addr, bit) \ ((volatile uint32_t *)(BITBAND_SRAM_BASE + ((uint32_t)(addr) - BITBAND_SRAM_REF) * 32 + (bit) * 4)) /* Macro to calculate bit-band alias address for Peripheral */ #define BITBAND_PERI(addr, bit) \ ((volatile uint32_t *)(BITBAND_PERI_BASE + ((uint32_t)(addr) - BITBAND_PERI_REF) * 32 + (bit) * 4))
Example
This example shows how to set and clear bit 3 of a variable in SRAM using bit banding. It demonstrates atomic bit manipulation without affecting other bits.
c
#include <stdint.h> #include <stdio.h> #define BITBAND_SRAM_REF 0x20000000 #define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_SRAM(addr, bit) \ ((volatile uint32_t *)(BITBAND_SRAM_BASE + ((uint32_t)(addr) - BITBAND_SRAM_REF) * 32 + (bit) * 4)) int main() { uint32_t var = 0x00; // Variable in SRAM volatile uint32_t *bit3 = BITBAND_SRAM(&var, 3); // Bit 3 alias printf("Initial var = 0x%02X\n", var); *bit3 = 1; // Set bit 3 printf("After setting bit 3, var = 0x%02X\n", var); *bit3 = 0; // Clear bit 3 printf("After clearing bit 3, var = 0x%02X\n", var); return 0; }
Output
Initial var = 0x00
After setting bit 3, var = 0x08
After clearing bit 3, var = 0x00
Common Pitfalls
Common mistakes when using bit banding include:
- Using addresses outside the bit-band region (SRAM: 0x20000000–0x200FFFFF, Peripheral: 0x40000000–0x400FFFFF).
- Not using volatile pointers, which can cause the compiler to optimize away bit accesses.
- Confusing the bit number (0-7) within a byte.
- Trying to bit-band on flash memory or other non-bit-band regions.
Always verify the target address is within the correct bit-band region and use the correct formula.
c
/* Wrong: Using non-volatile pointer and wrong address */ uint32_t var = 0; uint32_t *bit5 = (uint32_t *)(0x20001000 + 5 * 4); // Incorrect calculation and missing volatile *bit5 = 1; // May not work as expected /* Correct: Use volatile and proper macro */ volatile uint32_t *bit5_correct = BITBAND_SRAM(&var, 5); *bit5_correct = 1; // Correct atomic bit set
Quick Reference
Remember these key points for bit banding on ARM Cortex-M:
- Bit-band regions:
SRAM: 0x20000000–0x200FFFFF
Alias: 0x22000000–0x23FFFFFF
Peripheral: 0x40000000–0x400FFFFF
Alias: 0x42000000–0x43FFFFFF - Use the formula:
alias = alias_base + (byte_offset * 32) + (bit_number * 4) - Access bits atomically by reading/writing 32-bit words at alias addresses.
- Use
volatilepointers to prevent compiler optimizations.
Key Takeaways
Bit banding lets you atomically access and modify individual bits via special alias addresses.
Calculate the alias address using the bit-band base, byte offset, and bit number with the formula provided.
Always use volatile pointers and ensure the target address is within the bit-band region.
Bit banding works only on SRAM and peripheral memory regions defined by ARM Cortex-M.
Use bit banding to avoid read-modify-write issues when changing single bits in embedded systems.