Sei sulla pagina 1di 12

1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

Contents [hide]

1 Introduction
2 What Is Bit-Banding Feature?
3 Advantages of Bit-Banding (Applications)
3.1 Example 1
3.2 Example 2
4 References and Read More

Introduction
If you have ever taken a part of developing a firmware for a complex device,
then you should have seen or used bit-field variables. In my previous job, I
was in the development team of a complex tracking device for vehicles,
where the firmware was written from the ground-up using bare metal C. The
firmware was responsible for controlling the communication between the
GSM, GPS, Zigbee/WiFi, RS-232 Serial, and the RTC module with the MCU,
besides sampling analog data and controlling the device digital outputs.
With this level of complexity and interleaved tasks, you’ll either use an off-
the-shelf RTOS with scheduling between tasks feature, or use bare metal C,
like my case here. You have to develop a flag-driven firmware, where most
events in the device have a special 1-bit-long flag variable (true or false).

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 1/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

Now, if you allocate a dedicated integer variable for each flag, then you will
end up with running out the free memory space. In this case bit-field
variables can save a lot of space for you. Using this method, the same
location in the memory is shared among more than one variable in the
struct.

Another usage of the bit-field variables is implementing some protocol with


a variable bit-long fields frame. In this case building a struct with bit-field
variables also saves you a good amount of memory space. Please revise the
article about struct and union in embedded C if you need to know more.

As any other solution in engineering world, it’s not always a win-win


situation. Bit-fields save place in data memory, and they also provide a
simplified way to set and get values (that aren’t byte-aligned) rather than
using bitwise operations. On the other hand, this means that whenever you
use a bit-field variable, the processor/compiler will perform READ-MODIFY-
WRITE operations. As the memory location is shared with others, then the
compiler will read the entire variable to store it in a temporary place, mask
other fields, change the value and then restore the value of unchanged fields
(this is what is called READ-MODIFY-WRITE operation).

So it’s true that we saved some space in the SRAM, but we will need more
instructions for each reading/writing operation in the Flash memory.

Accessing a bit-field variable is another concern when using bit-field. It is


not an atomic operation, which could lead to faults in some critical code
sections. Especially for shared bit-field variables between interrupts and
processes.

In a nutshell, using bit-field variables is more efficient for SRAM but less for
flash and the speed of the code execution. To this end, the feature of bit-
banding was introduced in ARM Cortex-M3 MCUs to enhance the process
considerably. So let’s know more about it!

What Is Bit-Banding Feature?


Writing a portable code is one of the concerns for developers, and while
dealing with bit-fields is not standard in all compilers, it is not very advisable
to use.

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 2/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

When a feature is available in the hardware itself, you will not have any
issues in porting the code from vendor to vendor while both are using the
same ARM Cortex-M3 core.

ARM Cortex-M3 features a 1 MB area in SRAM memory called bit-band


region. In this region each bit can be accessed individually. To access to bit-
band region bits you need to do so via an aliased region, where each word
in this region is an alias to one bit in the bit-band region.
ARM Cortex-M3 Memory Map: The bit-band region starts with 0x20000000
address and the alias starts with 0x22000000. Adapted from: Cortex-M3
Technical Reference Manual
To map each bit in bit-band region you need 1 word in the alias region.
Apparently, the size of bit-band alias will be 32-MB.

As a condensed explanation, to set the value of a bit from bit-band region


you need to change the value of the LSB in the alias address. However, you
still can deal with variables in bit-band region as normal.

ARM Cortex-M3 Memory Map: The bit-band region starts with 0x20000000 address and
the alias starts with 0x22000000. Adapted from: Cortex-M3 Technical Reference Manual

Access to this region is carried out via the system interface bus. An atomic
READ-MODIFY-WRITE operation to the bit-band region will be executed
when a data write access is done to the bit-band alias memory range, but
this time all are done by the hardware and no extra code will be produced
from the compiler.

Moreover, the same feature is available for another 1 MB region for the
peripheral region.

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 3/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

Adapted from: Cortex-M3 Technical Reference Manual

What was in SRAM bit-band region applies here. To access the 1 MB bits
you need to access them using the alias region. This is very useful to make
an easier way to access and program  the control and status registers.

Cortex-M3 does not have special instructions for bit operations. We need to
use direct access to the address in the bit-band region. We will see later how
to do that using C code.

Adapted from: Cortex-M3 Technical Reference Manual

Advantages of Bit-Banding
(Applications)

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 4/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

1. Changing the value of register’s bits using atomic operation (the READ-
MODIFY-WRITE operation cannot be interrupted by other activities).

2. Make flags variables instead of packed bit fields in C (which is not


advised for a portable code).

3. Implement serial data transfers using GPIO ports to serial devices (AKA
bit-banging).

Example 1
First, you need to know the following formula to calculate each bit (from bit-
band region) alias address. This formula is adapted from Cortex-M3
technical reference manual:

bit_word_offset = (byte_offset x 32) + (bit_number × 4)


bit_word_addr = bit_band_base + bit_word_offset

Where:
Bit_word_offset is the position of the target bit in the bit-band memory
region.
Bit_word_addr is the address of the word in the alias memory region that
maps to
the targeted bit.
Bit_band_base is the starting address of the alias region.
Byte_offset is the number of the byte in the bit-band region that contains
the targeted bit.
Bit_number is the bit position (0-7) of the targeted bit.

We will use bit-band feature to set a pin high if a button is pressed and set a
pin low if it’s released.

I will use EFM32LG starter kit (EFM32LG STK3600) to program the ARM
Cortex-M3 CPU.

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 5/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

Cortex-M3 Memory Map

In this application, we need to write a pin connected to an LED high/low and


read another pin from GPIO connected with a push button.

I will add a set of defines to do calculations needed for bit-banding, let’s


break them down:

1 #define PERI_BASE 0x40000000


2  
3 #define BITBAND_PERI_BASE 0x42000000

PERI_BASE is the base address of bit-band region for peripherals.

BITBAND_PERI_BASE is the base address of bit-band alias region for


peripherals.

1 #define BITBAND_PERI(a,b) ((BITBAND_PERI_BASE + (a-PERI_BASE)*32 +

This define is a C micro processor function to calculate the address of word


alias of the bit from bit-band region. According to the previously mentioned
formula:

bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)

1 #define PE_DOUT_SET_BASE 0x400060A0


2 #define PE_DOUT_CLEAR_BASE 0x400060A4
3 #define PB_DIN_BASE  0x40006040

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 6/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

These are the base addresses for the related registers to set the pin high/low
from portE (one register to set the pin and one to clear it) and to read a pin
value from the portB.

Note: I used C Preprocessor #if #else condition to switch between normal


and bit-banding options.

1 #include "em_device.h"
2 #include "em_cmu.h"
3 #include "em_emu.h"
4 #include "em_gpio.h"
5 #include "em_chip.h"
6  
7 #define bitband 0
8  
9 #define PERI_BASE 0x40000000
10 #define BITBAND_PERI_BASE 0x42000000
11  
12 #define BITBAND_PERI(a,b) ((BITBAND_PERI_BASE + (a-PERI_BASE)*32 +
13  
14 #define PE_DOUT_SET_BASE 0x400060A0
15 #define PE_DOUT_CLEAR_BASE 0x400060A4
16 #define PB_DIN_BASE  0x40006040
17  
18 #define PE_b2_SET *((volatile unsigned int *)(BITBAND_PERI(PE_DOUT
19 #define PE_b2_CLEAR *((volatile unsigned int *)(BITBAND_PERI(PE_DO
20 #define PB_b9 *((volatile unsigned int *)(BITBAND_PERI(PB_DIN_BASE
21  
22 int main(void
void) {
23     /* Initialize chip */
24     CHIP_Init();
25  
26     /* Enable clock for GPIO module */
27     CMU_ClockEnable(cmuClock_GPIO, true
true);
28  
29     /* Configure PB with alternate drive strength of 0.5mA */
30     GPIO_DriveModeSet(gpioPortB, gpioDriveModeLowest);
31  
32     /* Configure PB9 as an input for PB0 button with filter enable
33     GPIO_PinModeSet(gpioPortB, 9, gpioModeInput, 1);
34  
35     /* Configure PE2 as a push pull with alternate strength for LE
36     GPIO_PinModeSet(gpioPortE, 2, gpioModePushPullDrive, 0);
37  
38     while
while (1) {
39  
40 #if bitband ==1
41         if
if(PB_b9)
42 #else
43         if
if (GPIO_PinInGet(gpioPortB, 9))
44 #endif
45                 {
46 #if bitband ==1
47             PE_b2_SET=1;
48 #else
49             GPIO_PinOutSet(gpioPortE, 2);
50 #endif
51  
52         } else {
53 #if bitband ==1
54             PE_b2_CLEAR = 1;
55 #else
56             GPIO_PinOutClear(gpioPortE, 2);
57 #endif
https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 7/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

58  
59         }
60  
61     }
62 }

Example 2
1- Let’s set the address 0x20000000 to a value of 0x00000AAC using direct
access (without using bit-banding).

0x00000AAC

2- If we read the address 0x22000008 (The alias address of bit[2] in


0x20000000 word), the return value will be

3- Now let’s write 1 to 0x22000010.

4- The value of 0x20000000 word will become 0x00000ABC.

References and Read More


The Definitive Guide to ARM Cortex-M3 by Joseph Yiu

ARM Application Note 179.

ARM Cortex-M3 Technical Reference Manual.

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 8/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

6 Comments

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 9/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

Alan
31st December 2017 at 6:01 am

If the ARM series had separate “ports” instead of memory mapped I/O…
You could have instructions that only set a particular bit high / low, with
the rest in a high impedance “don’t change” mode.
Think of it as a variation on the 74245 (octal transceiver bus)

Oh well – gotta make do with what we have, I suppose. Unless you want
to emulate an ARM with an FPGA, of course.

Reply

Yahya Tawil
31st December 2017 at 7:12 am

To understand your comment well, do you mean by ports the GPIO


ports?

Reply

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 10/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

alfred
25th March 2018 at 8:49 am

Hi Yehya,

I am trying some stuff on a Tiva board and writing/reading some code in


C and Assembly.
If I understood correctly, some ports/addresses are natively mapped to a
bit-band region ?
Not every port/address can be used with bitband?
lets say i want to use a peripheral at address 0x41000000 with bit-
banding would that be possible?
who specifies what is bit-banded and what is not?

Thanks in advance,
Alfred

Reply

Yahya Tawil
25th March 2018 at 8:55 am

Hello Alfred

According to the images from ARM Cortex-M3 Technical Reference


Manual you can see that there is a 1-MB-long area in peripheral are
starting from 0x40000000 and ends 0x40100000, so 0x41000000 is
out of this range and accessed normally (not bit by bit).

Generally, any peripheral address (register) within 0x40000000 –


0x40100000 has an alias address for each bit in it.

You’re most welcomed

Reply

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 11/12
1/16/2019 Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4 - Atadiat

ryan
2nd June 2018 at 1:48 am

Shouldn’t this line #define PB_b9 *((volatile unsigned int *)


(BITBAND_PERI(PB_DIN_BASE,9))) be #define PB_b9 *((volatile unsigned
int *)(BITBAND_PERI(PB_DIN_BASE,6))) … the number 9 is actually 6

Reply

Yahya Tawil
2nd June 2018 at 10:25 am

I don’t think so. This invokes a call for the macro-function to calculate
the bit-band-address of the bit number 9 of port B. This should be
explicitly the same of the bit order number.

Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/ 12/12

Potrebbero piacerti anche