0
0
Cnc-programmingHow-ToBeginner · 4 min read

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 volatile pointers 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.