ARM Cortex-M3/M4 Bit Banding
“Bit Banding- A term used in ARM Cortex-M3/M4 architecture to indicate regions in processor memory map where individual bits can be accessed by a unique address.”
One of the major difference between Cortex-M0 and M3/M4 is Bit Banding. In ARM Cortex-M3/M4 memory map, there are 4-regions labeled as bit-band regions and bit-band alias respectively – Figure-1.
As shown in Figure-1, both the SDRAM and Peripheral Regions contain 1MB Bit Band and 32MB Bit Band alias regions. Actually the 1MB Bit Band is the region where individual bits are addressable via 4-byte unique address AND the Bit Band alias is the region within which addresses of individual bits in 1MB Bit Band region lies- Figure-2,3.
1. Why bit-band?
In almost majority of cases, processors can’t access a single bit in memory. In other words there is no such thing as “BSET” (bit-set) instruction. Normally when there is a requirement of bit manipulation, processor has to go through the Read-Modify-Write cycle i.e. a whole word (4-byte in case of 32-bit system) is fetched, target bit is modified by shift and logical operation like OR, AND, NOT, XOR etc., and finally the whole “WORD” is written back to memory. Sample macros for standard bit operations are given bellow.
/* bit operations macros */ #define __setbit(___reg, ___bit) ((___reg) |= (1U << (___bit))) #define __clearbit(___reg, ___bit) ((___reg) &= (~(1U << (___bit)))) #define __togglebit(___reg, ___bit) ((___reg) ^= (1U << (___bit))) #define __getbit(___reg, ___bit) (((___reg) & (1U << (___bit))) == (1U << (___bit)))
The read-modify-write operation is indeed an expensive operation which may cause some unwanted results especially in a multi threaded environment where multiple threads are performing operations on target memory contents.
Bit banding has the benefit of targeting single bit without any expensive (execution wise) operation like shift etc. This helps minimizing read-modify-write overhead.
Consider an example of GPIOs. Let say we want to toggle a specific GPIO pin at the rate of let say 5Mhz. This means each time we have to fetch respective GPIO pin Value register contents, toggle the target bit and write back to the GPIO value/data register. i.e.
GPIO_VAL_REG ^= (1U << ___gpPin); /* or */ GPIO_VAL_REG = GPIO_VAL_REG ^ (1U << ___gpPin);
The above operation is performed non-atomically as:
Now let say the GPIO_VAL_REG register is in bit band region; it means each bit can be accessed individually by a unique address in subsequent bit-band alias region.
In this case if we want to set/reset any of GPIO bit, all we have to do is to write (0,1) to respective bit associated memory address and the SOC will automatically perform the operation of specific bit atomically.
/* Set */ *(volatile unsigned int *)ADDRESS = 1; /* Reset */ *(volatile unsigned int *)ADDRESS = 0;
2. Address Calculation:
Now that we have explained Bit-banding in ARM Cortex-M3/M4, let see how we can calculate address (in bit-band alias) of a single bit in bit-band region. The formula for address calculation is given bellow.
Address: Bit Band Alias Region Base Address + (byte offset from bit band region x 32 ) + (bit number x 4 )
Let’s say as an example, we want to calculate the bit address of 4th bit in SRAM 2nd byte of bit-band region. In this case:
Alias Base Address: 0x22000000
Byte Offset: 2 (from bit-band region 0x20000000)
Bit No: 3 (4th bit)
Address: 0x22000000 + (2 x 32 ) + (3 x 4)
/* Set */ (*(volatile unsigned int *)0x2200004C) = 1; /* Reset */ (*(volatile unsigned int *)0x2200004C) = 0;