Search code examples
cbit-fields

Using bit fields for AVR ports


I'd like to be able to use something like this to make access to my ports clearer:

typedef struct {
    unsigned rfid_en: 1;
    unsigned lcd_en: 1;
    unsigned lcd_rs: 1;
    unsigned lcd_color: 3;
    unsigned unused: 2;
} portc_t;

extern volatile portc_t *portc;

But is it safe? It works for me, but...

1) Is there a chance of race conditions?

2) Does gcc generate read-modify-write cycles for code that modifies a single field?

3) Is there a safe way to update multiple fields?

4) Is the bit packing and order guaranteed? (I don't care about portability in this case, so gcc-specific options to make it Do What I Mean are fine.)


Solution

    1. Handling race conditions must be done by operating system level calls (which will indeed use read-modify-writes), GCC won't do that.

    2. Idem., and no GCC does not generate read-modify-write instructions for volatile. However, a CPU will normally do the write atomically (simply because it's one instruction). This holds true if the bit-field stays within an int for example, but this is CPU/implementation dependent; I mean some may guarantee this up to 8-byte value, while other only up to 4-byte values. So under that condition, bits can't be mixed up (i.e. a few written from one thread, and others from another thread won't occur).

    3. The only way to set multiple fields at the same time, is to set these values in an intermediate variable, and then assign this variable to the volatile.

    4. The C standard specifies that bits are packed together (it seems that there might be exceptions when you start mixing types, but I've never seen that; everyone always uses unsigned ...).

    Note: Defining something volatile does not cause a compiler to generate read-modify-writes. What volatile does is telling the compiler that an assignment to that pointer/address must always be made, and may not be optimised away.

    Here's another post about the same subject matter. I found there to be quite a few other places where you can find more details.