Structure and bit fields
In this article, we delve into the concept of structure bit fields, exploring how to use them effectively to optimize memory consumption.
What Are Bit Fields?
- Bit fields are a feature in C and C++ that allow us to allocate specific numbers of bits for individual variables within a structure.
- They are useful for optimizing memory usage when dealing with bit-level data within larger data structures.
Understanding Bit Fields with an Example
Let’s consider our previous example.
Here, we have a packet of 32 bits and the CRC(Cyclic Redundancy Check) is of just 2 bits.
In the previous exercise, we extracted the CRC and stored it in a variable of type U8 and CRC is equal to the extracted value. So, here we are losing 6 bits. Because only two bits are being utilized.
How to prevent this?
To prevent this we have to rewrite our structure using bit fields. Here are the key steps:
Selecting Appropriate Data Types:
Before using bit fields in a structure first you must select the appropriate data type for the member elements. So, that is a very important step.
Select a proper data type, whether you are going to use U8, U16, U32 whatever. So, you have to select that first. That selection depends upon what you are trying to do.
Implementing Bit Fields:
Look at Figure 1, I have a packet of 32 bits and I just want to extract various fields into variables. That’s why, I start with a data type U32 and then I create a variable, let’s say CRC. But I will instruct the compiler to use just 2 bits of this U32, which is a 32-bit memory. That’s why I write like this. I give a colon here and then I write 2.
There will be 32 bits of memory. So, this is the memory of 32 bits and inside this only two bits will be given to the variable CRC, as shown in Figure 2.
After that, Status. Again I continue with the same data type U32 and I write another variable status and :1. The next 1 bit will be given to the variable status.
So, I again take the U32 data type, don’t change the data type, until you consume all the remaining bits. The code is shown in Figure 2.
So, like that, you are going to consume all the 32 bits and you have already asked the compiler to access those bit fields using a dedicated variable name.
Efficient Memory Usage:
If you do this, you can see that both your requirements are fulfilled.
The first requirement was to store different bit fields in a separate variable and our second requirement is to minimize memory consumption.
The output is shown in Figure 3. Here is an output of our old program and the new program. You can see that the output looks the same(New and Old), but our old program consumes 10 bytes.
This(NEW output) is output with a bit field modification and here you can see that the structure size is just 4 bytes.
We come to know that by using bit fields,
- We reduced the memory consumption of a structure.
- Whenever you find codes that are related to networking activities, then you often find these bit field structures. So, these are heavily used when you deal with networking activities in code.
Order of Member Elements:
Also you should note one point, the order of the member elements doesn’t matter actually. Because each member element will anyway go to consume only that many amounts of bits. So, but the order in which they appear in the memory may change. That’s why it is not recommended actually to change the order.
I wrote this order to refer to my packet information. Most of the time you will be implementing bit fields like that by referring to something. So, don’t change the order of the member elements.
So, even if you change the order of the member elements the output will come the same for this application(Figure 4).
But that will cause a problem when you send that structure value as a 32-bit value to some other function or some other module. In that case, you may face issues.
That’s about bit fields.
Get Full Course on Microcontroller Embedded C Programming Here.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1