1

I have the following

/* Size 16 bytes */
typedef struct __attribute__((packed)) {

    uint16_t v1;    // 2
    uint16_t v2;    // 2
    uint16_t v3;    // 2
    uint16_t v4;    // 2

    uint8_t rsvd[6];

    uint16_t crc;   // 2

} heCell_t;

typedef struct __attribute__((packed)) {

    heCell_t c0;
    heCell_t c1;
    heCell_t c2;
    heCell_t c3;

} hePag_t;

typedef union {
    hePag_t Page[32];
    heCell_t Cell[128];
} heData_t;

Due to gcc warning: "setting incorrect section attributes for .rodata.$Flash3"

for this line

const heData_t heData __RODATA(Flash3);

I have to initialize heData with something, which is fine by me, as long as all values will be all 0xFF (default flash erased)

const heData_t heData __RODATA(Flash3) = { 0xFF };

But there are some warnings

(near initialization for 'heData.Page[0]') [-Wmissing-braces]   
mame98
  • 1,271
  • 12
  • 26
user1797147
  • 915
  • 3
  • 14
  • 33
  • 4
    `{0xFF}` will initialize first element only. And you can't initialize a `union` with some scalar...BTW, what is the point of having some uninitialized read-only data??? You probably want to do something else. – Eugene Sh. Jul 05 '16 at 17:30
  • You can have a lot of reasons that you don't want to initialize something in embedded. Eg. you have a big buffer that is a waste of time when MCU is start up. But here, I have a flash variable and when MCU is erased, I know that all area is 0xFF. So there is no need to initialize anything. – user1797147 Jul 05 '16 at 17:54
  • @Eugene Sh. I am confident that `{0xFF}` will initial the entire object, the first with `0xFF` and the rest with a zero bit pattern. There is no partial initialization in C. See http://stackoverflow.com/q/13104767/2410359 and C11 §6.7.9 21 – chux - Reinstate Monica Jul 05 '16 at 17:56
  • agree, but how can I leave as is and remove gcc message – user1797147 Jul 05 '16 at 18:03

2 Answers2

2

This will clear the warning:

const heData_t heData  __RODATA(Flash3)={.Page={{{0xff}}}};

However only the first byte will be 0xff, the rest are all 0x00. To fix that you might try (with gcc):

typedef union {
    hePag_t Page[32];
    heCell_t Cell[128];
    uint8_t bytes[128*sizeof(heCell_t)];
} heData_t

...

const heData_t heData __RODATA(Flash3)={.bytes[0 ... 128*sizeof(heCell_t)-1]=0xff};

That will initialize all of the data with 0xff.

A reference

evaitl
  • 1,365
  • 8
  • 16
  • The first line DOESN'T clear the warning but second explanation, yes, make sense. Absolute fantastic, many thanks!!! How can I give you a lot of points for that? Thanks very much man ! – user1797147 Jul 05 '16 at 18:30
  • GCC is cool. If only they didn't make the parse trees so ugly and hard to get at for political reasons. I tried the first line and it cleared the warning for me. You have to do all of the braces though. Good luck. It was a good question. – evaitl Jul 05 '16 at 18:35
  • Do note that the form of array initializer used here is a GNU extension. Standard C provides for single-element designators, but not range designators. Of course, the code overall relies on other GNU extensions, too, so that probably doesn't matter. – John Bollinger Jul 05 '16 at 18:37
2

I have to initialize heData with something, which is fine by me, as long as all values will be all 0xFF (default flash erased).

The only way to initialize an object, or any part of one, with values different from zero is to present an explicit initializer for that part. You have a moderately large object to initialize with explicit initializers, but since you want to initialize it with a repeating pattern, the preprocessor can help you. Here's one way to do it:

#define TWICE(...) __VA_ARGS__, __VA_ARGS__
#define FOUR_TIMES(...) TWICE(__VA_ARGS__), TWICE(__VA_ARGS__)
#define SIXTEEN_TIMES(...) FOUR_TIMES(TWICE(__VA_ARGS__))     
#define TIMES_128(...) SIXTEEN_TIMES(FOUR_TIMES(TWICE(__VA_ARGS__)))

/* Size 16 bytes */
typedef struct __attribute__((packed)) {

    uint16_t v1;    // 2
    uint16_t v2;    // 2
    uint16_t v3;    // 2
    uint16_t v4;    // 2

    uint8_t rsvd[6];

    uint16_t crc;   // 2

} heCell_t;

typedef struct __attribute__((packed)) {

    heCell_t c0;
    heCell_t c1;
    heCell_t c2;
    heCell_t c3;

} hePag_t;

typedef union {
    hePag_t Page[32];
    heCell_t Cell[128];
} heData_t;

const heData_t heData __RODATA(Flash3) = {
    .Cell = { TIMES_128(
            { 0xffff, 0xffff, 0xffff, 0xffff, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0xffff})
    }
}; 

Although it's a bit uglier than the solution offered in the other answer, it is standard C. (The initializer part is standard, that is. There are GNU extensions inherited from the question.)

John Bollinger
  • 160,171
  • 8
  • 81
  • 157