bit banding
WHAT?¶
Bit Banding is a method of performing atomic bitwise modifictions to memory. If you have used small PIC micros before these are like BSF and BCF (Bit Set and Bit Clear)
WHY?¶
Usually changing a word in memory requires a read-modify-write cycle. If this operation is interrupted there can be data loss.
Information
Read (0xaa) from A to register
Interrupt!
Write (0x33) to A
Return!
Modify (0xaa to 0xab)
Write (0xab) to A
(0x33) data has been lost!
The is avoided by disabling interrupts/using a supervisor mode or by using bit-banding as shown here.
HARDWARE¶
Two 1MB 'bit-band' regions, one in the peripheral memory area and one in the SRAM memory areas are each mapped to a 32MB virtual 'alias' region. Each bit in the bit-band region is mapped to a 32bit word in the alias region.
The first bit in the 'bit-band' peripheral memory is mapped to the first word in the alias region, the second bit to the second word etc.
Image: UM1360 NXP LPC17XX User Manual, Accessed 12/1/2011
Writing a value to the alias region with Least Significant Bit i.e. bit[0] set to 1 will write a value of 1 to the bit-band bit. Conversely writing a value of 0 will clear the bit-band bit. The value of the bits[31:1] in the alias region for any word are unmapped and will have no effect on the bit-band value.
Calculating addresses¶
calculate_address
alias_word_address = alias_region_base + (bit_band_byte_offset x 32) + (bit_number x 4)
alias_word_address => Where to write to in order to change bit-band value
alias_region_base => Starting memory location of alias
bit_band_byte_offset => Difference between target bit-band byte address and base of bit-band memory location
bit_number => 0-7 the number of the bit in the bit-band you would like to change.
0x20000000 ==> Base address of SRAM
0x22000000 ==> Base address of SRAM alias region
0x40000000 ==> Base address of peripheral region
0x42000000 ==> Base address of peripheral alias region
How it is done¶
// Define base address of bit-band #define BITBAND_SRAM_BASE 0x20000000 // Define base address of alias band #define ALIAS_SRAM_BASE 0x22000000 // Convert SRAM address to alias region #define BITBAND_SRAM(a,b) ((ALIAS_SRAM_BASE + (a-BITBAND_SRAM_BASE)*32 \ + (b*4))) // Define base address of peripheral bit-band #define BITBAND_PERI_BASE 0x40000000 // Define base address of peripheral alias band #define ALIAS_PERI_BASE 0x42000000 // Convert PERI address to alias region #define BITBAND_PERI(a,b) ((ALIAS_PERI_BASE + (a-BITBAND_PERI_BASE)*32 \ + (b*4))) //Define some memory address #define MAILBOX 0x20004000 //Define a hardware register #define TIMER 0x40004000 // Mailbox bit 0 #define MBX_B0 *((volatile unsigned int *)(BITBAND_SRAM(MAILBOX,0))) // Mailbox bit 7 #define MBX_B7 *((volatile unsigned int *)(BITBAND_SRAM(MAILBOX,7))) // Timer bit 0 #define TIMER_B0 *((volatile unsigned char *)(BITBAND_PERI(TIMER,0))) // Timer bit 7 #define TIMER_B7 *((volatile unsigned char *)(BITBAND_PERI(TIMER,7))) int main(void){ unsigned int temp = 0; MBX_B0 = 1; // Word write temp = MBX_B7; // Word read TIMER_B0 = temp; // Byte write return TIMER_B7; // Byte read }
Code: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0179b/CHDJHIDF.html modified for naming used in text
More Code:¶
There is some nicer written code: http://www.micromouseonline.com/blog/2010/07/13/bit-banding-in-the-stm32 it does the same thing but it a bit prettier.
Recap¶
Use this method when you need atomic (non interruptible) changes to a bit in SRAM or peripheral mapped memory.
If you don't need atomic changes then this process is slower as you can only change one bit at a time.
In certain circumstances (changing lots of bits) it may be quicker to disable interrupts, make the changes and re-enable interrupts.
Hope this helps
Sources¶
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/Babgcaie.html
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka4203.html
http://www.micromouseonline.com/blog/2010/07/13/bit-banding-in-the-stm32
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0179b/CHDJHIDF.html