Eneko
Eneko

Reputation: 159

Need help understanding C struct

I am a newbie who has started programming embeded systems and I am working with someone else's code. However, there is a struct definition that I do not help to understand.

struct PACKED {
        uint8_t cmd;
        uint8_t int_status;
        uint8_t v[14];
    } rx, tx = { cmd : REG_ADDRES | 0x80, };

I would appreciate any help to understand the cmd : REG_ADDRES | 0x80, line.

Thanks in advance.

Upvotes: 0

Views: 134

Answers (3)

glglgl
glglgl

Reputation: 91017

Essentially, this part defines the contents of this variable.

It is an extension of the compiler you use; C99 defines it in a slightly different way. There you would write

struct PACKED {
    uint8_t cmd;
    uint8_t int_status;
    uint8_t v[14];
} rx, tx = { .cmd = REG_ADDRES | 0x80 };

This way of declaring things is quite dangerous, though, as it is wasy to skip that indeed only tx is init'ed.

A better way would be

// first declare the struct as a type
struct PACKED uart {
    uint8_t cmd;
    uint8_t int_status;
    uint8_t v[14];
};
struct PACKED uart rx;
struct PACKED uart tx = { .cmd = REG_ADDRES | 0x80 };

Upvotes: 2

hyde
hyde

Reputation: 62777

That is combined struct type definition, and definition of two variables of that type. So it is same as code below, except code below is fixed to use the C designated initializer syntax:

struct PACKED {
        uint8_t cmd;
        uint8_t int_status;
        uint8_t v[14];
};

struct PACKED rx; // uninitialized, do not use until initialized elsewhere
struct PACKED tx = { .cmd = REG_ADDRES | 0x80 }; // cmd field initialized with value

Note that entire tx is initialized above, the fields that are not given explicit value are initialized to 0.

And if you wonder what REG_ADDRES | 0x80 means, it is simple integer expression, a calculation using bitwise OR, so it sets bit number 7 as one, and takes other bits 0..6 from REG_ADDRES as they are there.

Upvotes: 4

CinCout
CinCout

Reputation: 9619

What the line tx = { cmd : REG_ADDRES | 0x80, }; is doing is that it is initializing an object named tx of type PACKED whose first variable (i.e. uint8_t cmd) is getting initialized with the value REG_ADDRES | 0x80 (which is the bitwise OR of REG_ADDRES and 0x80).

In code, it is the same as:

struct PACKED
{
    uint8_t cmd;
    uint8_t int_status;
    uint8_t v[14];
};

main()
{
    struct PACKED tx;
    tx.cmd = REG_ADDRES | 0x80;
}

Upvotes: 2

Related Questions