There are some pieces of code that regularly appear when programming embedded systems. They are not really design patterns but rather small tricks that might be confusing the first time you see them.

Bit manipulation

Registers in peripherals typically have single bit fields. It is often needed to clear, set, test or toggle them.

brush: c
unsigned int reg;
reg &= ~(1 << offset); // Clear a bit
reg |=  (1 << offset);  // Set a bit
reg ^=  (1 << offset);  // Toggle a bit
if (reg & (1 << offset)) { /// Test a bit
  // Bit is set
}
else {
  // Bit is not set
}

Create a mask

You often need to create a mask with a certain width. The code below works even for fields that take the whole data width.

brush: c
const int width = 4;
unsigned int mask = ((1 << width) - 1); // mask = 0xf

Clear a field

Clearing a field of several bits in a variable.

brush: c
unsigned int reg;
const unsigned int mask = 0x3f;
const int offset;

reg &= ~(mask << offset);

Setting all bits in a field

Setting all bits in a field to 1.

brush: c
unsigned int reg;
const unsigned int mask = 0x3f;
const int offset;

reg |= (mask << offset);

Field access

When accessing a hardware register in a peripheral, this sequence is often used to extract a bit fields. The C standard has support for them though you still see them.

brush: c
const int offset = 3;
const unsigned int mask = 0x7f;
unsigned int data;
unsigned int field = (data >> offset) & mask; // Get a field
data = (data & (mask << offset)) | ((field & mask) << offset);

Circular buffer

When accessing a circular buffer, address increments can be done quickly if the size is a power of two.

brush: c
unsigned int offset;
offset = (offset + step) & ((1 << width) - 1);

Testing if a number is a power of two

Finding if a number is a power of two is easy.

brush: c
unsigned int number;

if ((number & (number - 1)) == 0) {
  // power of two
}
else {
  // non-power of two
}

Comment