The Cortex-M3 processor implements bit-band regions that allow single-bit atomic read-modify-write operations to be performed on peripheral registers without the overhead of a read-modify-write sequence. This enables efficient synchronization between multiple processors trying to access shared resources.
Introduction to Bit-banding
Bit-banding maps a complete word in memory map to a single bit in the bit-band region. This allows individual bits to be addressed as if they were words themselves. The Cortex-M3 implements two bit-band regions – one for Data memory and one for Peripheral memory. Any access to the bit-band region is automatically mapped to the corresponding bit in the aliased memory.
For example, writing to address 0x2200 0000 will set bit 0 of address 0x2000 0000. Reading from 0x2200 0000 will return the value of bit 0 of address 0x2000 0000. This mapping allows atomic read-modify-write operations on individual bits of a peripheral register.
Bit-band Region for Data Memory
The bit-band region for Data memory starts at 0x20000000 and ends at 0x200FFFFF. It maps each word in the SRAM memory region 0x20000000 – 0x2000FFFF to a bit addressable location. For example, bit 0 of each SRAM word is aliased to a bit-band address in the range 0x20000000 – 0x200000FF.
So a write to address 0x20000004 will set bit 1 of the SRAM word at address 0x20000001. A read from 0x20000004 will return the value of bit 1 of SRAM address 0x20000001. This scheme allows individual bits of SRAM to be read and written atomically.
Data Memory Bit-band Region Address Mapping
The mapping between SRAM address and bit-band alias address is as follows:
- Bit 0 of SRAM word N is mapped to bit-band address 0x02000000 + (N * 4)
- Bit 1 of SRAM word N is mapped to bit-band address 0x02000000 + (N * 4) + 0x4
- Bit 2 of SRAM word N is mapped to bit-band address 0x02000000 + (N * 4) + 0x8
And so on, up to bit 31 of each SRAM word. This allows each SRAM bit to be individually addressed via the bit-band region.
Bit-band Region for Peripheral Memory
The bit-band region for Peripheral memory starts at 0x40000000 and ends at 0x400FFFFF. It maps each word in the peripheral memory region 0x40000000 – 0x400FFFFF to a bit addressable location.
For example, bit 0 of each peripheral register word is aliased to a bit-band address in the range 0x40000000 – 0x400000FF. A write to address 0x40000004 will set bit 1 of the peripheral register at address 0x40000001. A read from 0x40000004 will return bit 1 of that peripheral register.
Peripheral Memory Bit-band Region Address Mapping
The mapping between peripheral register address and bit-band alias address is as follows:
- Bit 0 of peripheral register N is mapped to bit-band address 0x40000000 + (N * 32)
- Bit 1 of peripheral register N is mapped to bit-band address 0x40000000 + (N * 32) + 0x4
- Bit 2 of peripheral register N is mapped to bit-band address 0x40000000 + (N * 32) + 0x8
And so on, up to bit 31 of each peripheral register word. This allows atomic read-modify-write access to individual bits of peripheral registers.
Use Cases for Bit-banding
Some typical use cases for bit-banding in Cortex-M3 are:
- Atomically setting or clearing individual bits in peripheral registers like GPIO, NVIC, etc.
- Implementing mutexes and semaphores using bit-band aliases for SRAM locations
- Atomic bit toggling without read-modify-write sequence
- Efficient multi-core synchronization by accessing shared resource bits
- Setting thread ready/wait bits
- Signaling event flags between threads
Example: Atomic Bit Set in GPIO Register
To atomically set bit 5 of the GPIOB->ODR register to 1: #define GPIOB_ODR_BB (PERIPH_BB_BASE + (GPIOB_ODR_OFFSET * 32) + (5 * 4)) ATOMIC_SET_BIT(GPIOB_ODR_BB)
This requires just a single write to the bit-band alias address, and is more efficient than a read-modify-write sequence.
Example: Thread Synchronization using Bit-banding
Threads can use bit-banding for synchronization and signaling. For example: #define THREAD_A_Ready (SRAM_BB_BASE + (ReadyFlag_OFFSET * 4)) void Thread_A() { // Indicate thread A is ready ATOMIC_SET_BIT(THREAD_A_Ready); // Wait for thread B while(ATOMIC_READ_BIT(THREAD_B_Ready) == 0) { } // Now both threads are ready, do work… } void Thread_B() { // Wait for thread A while(ATOMIC_READ_BIT(THREAD_A_Ready) == 0) { } // Indicate thread B is ready ATOMIC_SET_BIT(THREAD_B_Ready); // Now both threads are ready, do work… }
This allows efficient synchronization and signaling without locks or semaphores.
Limitations of Bit-banding
While bit-banding enables atomic RMW operations, it has some limitations:
- Only single bit accesses are atomic
- 32-bit or larger accesses are not atomic
- Not supported for writes to flash memory
- Requires software overhead to calculate bit-band alias addresses
- Only available on Cortex-M3, M4 and M7 processors
So bit-banding works best for synchronizing access to peripheral registers and SRAM bits, but cannot be used as a general purpose atomic operation mechanism.
How Bit-banding Works Internally
The Cortex-M3 memory protection unit (MPU) is used to set up the bit-band regions and mapping between bit-band addresses and aliased memory locations. The MPU regions attribute the bit-band areas as “Strongly-ordered” memory, which has specific cache coherency requirements.
This forces the processor to read the data directly from aliased memory location on each bit-band access, rather than relying on cached data. This ensures that any changes made by other processors or DMA are immediately visible through the bit-band alias.
In addition, the WIC (Write Invalidate Cache) control signal is asserted on writes to bit-band locations. This invalidates any cached data from the aliased memory location, again ensuring coherency between the bit-band access and aliased memory.
The MPU and WIC invalidation provide the mechanisms to enable atomic bit manipulation using the bit-band regions in Cortex-M3 processors.
Conclusion
In summary, bit-band regions in Cortex-M3 allow atomic single-bit read-modify-write operations on peripheral registers and SRAM locations. This enables efficient synchronization and resource sharing between multiple processors without locks.
Typical use cases include setting/clearing peripheral register bits, implementing mutexes, signaling event flags between threads, and other multi-core communication. However, bit-banding has limitations and is only supported in Cortex-M3 and newer ARM cores.
By mapping peripherals and SRAM words into individually addressable bits, bit-banding provides an efficient mechanism for atomic bit manipulation in microcontroller applications.