Действительно ли достаточно объявить экземпляр переменной определенного типа структуры как энергозависимый (если к ее полям получают доступ в повторно используемом коде), или нужно объявить определенные поля структуры как энергозависимые?
Формулируемый по-другому, что является семантическими различиями (если таковые имеются) между:
typdef struct {
uint8_t bar;
} foo_t;
volatile foo_t foo_inst;
и
typedef struct{
volatile uint8_t bar;
} foo_t;
foo_t foo_inst;
Я распознаю, что объявление переменной определенного типа указателя как энергозависимая (например, энергозависимый uint8_t * нечто) просто сообщает компилятору, что адрес, на который указывает нечто, может измениться, не делая оператор о значениях указанным нечто. Неясно мне, содержит ли аналогия для переменных определенного типа структуры.
В вашем примере они одинаковы. Но вопросы вращаются вокруг указателей.
Во-первых, volatile uint8_t *foo;
говорит компилятору, что указываемая память является переменной. Если вы хотите пометить сам указатель как волатильный, то нужно сделать uint8_t * volatile foo;
И вот тут-то и заключаются основные различия между пометкой структуры как волатильной и пометкой отдельных полей. Если бы у вас было:
typedef struct
{
uint8_t *field;
} foo;
volatile foo f;
, то это действовало бы как:
typedef struct
{
uint8_t * volatile field;
} foo;
, а не как:
typedef struct
{
volatile uint8_t *field;
} foo;
Если вы заявляете структуру во власти, то все его члены также будут волатильными