Embedded C: Struct and Union

In this article we are going to discuss a couple of complex data structures in C language. Understanding struct and union is not only essential in learning C language in general, but also a vital need in embedded programming because they can make the life of an embedded developer much easier with abilities uniquely tuned up for this purpose.

Structure (Struct)

You can think of a struct as a way to aggregate a number of different variables of different data types in one entity that starts in a specific address in memory. Structures in C language are declared using the keyword struct :

Note : pay attention to the semicolon after the closing bracket.

A struct is a custom data type (user-defined) and the data fields in a struct are called members. You can declare and define structure variables after you declare the structure itself:

To declare and define at the same time, use:

Structure’s data members are accessible using the “.” operator:

Of course, pointers are widely used and to access data members in pointers, the “->” operator is used:

Note: a struct only resembles a template and the compiler won’t allocate any memory when you declare one. It only does that when you define a struct variable:

(It is required to use the struct keyword in this case, but we are going to show you how to define a new struct variable without it later in the post)

In some cases, only a number of bits is needed for a struct data member. For this purpose, you can use bit fields, which are designed specifically to reduce the needed memory amount to a minimum. To declare bit fields, use the “:” operator followed by the number of bits as an integer value:

In this example, element_a is one bit long, element_b is three bits and element_c is two bits with a default value set to 0.

It is not advisable to use bit fields because it is not a standard and may not be supported by all compilers in an identical way. However, this method can be used if you mind this particular point.

Unions

In some cases, you may need a type of variables that can be accessed in several ways (as several data types) and in the same memory location at the same time. Unions are used to provide this type of variables.

Declaring unions is similar to declaring structs using the union keyword:

Also, accessing data members is similar to structs:

In case of pointers:

The fundamental difference between the two is how data is allocated in memory. In structures, the compiler would allocate memory for each data member within the struct. While in unions, the compiler would allocate a block of memory equal to the largest data member in the union.

struct vs union

Using unions in software programming may not be very popular, but it is an important aspect in embedded programming. Using it as a type of a temporary memory or “scratch pad” is one of the common uses in embedded development. This can be done when it is needed to have a space in the memory to access and store different variable types (while no two of them are used at the same time). This is useful in embedded systems to reduce memory consumption.

Unions are also used to extract small blocks of data from a larger one:

In this example, you can access the timer’s 32-bit as one piece (TMR.val). Alternatively, you can access each byte individually (TMR.Bytes.Zero).

Using Struct and Union With Typedef Command

Using typedef command, you can define your own variable type. For example:

We used ulong name as an alias for unsigned long. Now we can use ulong to declare variables with unsigned long type.

The same thing applies with struct and union:

Now we can use sname to declare variables s1 and s2 with the defined struct type:

References

 

Leave a Reply

Your email address will not be published. Required fields are marked *