https://stackoverflow.com/questions/2044565/volatile-struct-semantics
In your example, the two are the same. But the issues revolve around pointers.
First off, volatile uint8_t *foo;
tells the compiler the memory being pointed to is volatile. If you want to mark the pointer itself as volatile, you would need to do uint8_t * volatile foo;
And that is where you get to the main differences between marking the struct as volatile vs marking individual fields. If you had:
typedef struct { uint8_t *field; } foo; volatile foo f;
That would act like:
typedef struct { uint8_t * volatile field; } foo;
and not like:
typedef struct { volatile uint8_t *field; } foo;
if you declare a structure with volatile then all its members will also be volatile
如果将一个结构体声明位volatile,则它的所有成员都是volatile。