2016-07-05 2 views
1

У меня есть следующиеЗаполните массив союзами со значениями в С

/* 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; 

Из-за предупреждения GCC: «Неправильная настройка раздел атрибутов .rodata $ Flash3»

для этой линии

const heData_t heData __RODATA(Flash3); 

Я должен инициализировать heData с чем-то, что меня устраивает, до тех пор, как все значения будут все (вспышки по умолчанию стертых) 0xFF

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

Но есть некоторые предупреждения

(near initialization for 'heData.Page[0]') [-Wmissing-braces] 
+4

'{0xFF}' будет инициализировать только первый элемент. И вы не можете инициализировать 'union' с помощью некоторого скаляра ... BTW, в чем смысл иметь некоторые неинициализированные данные только для чтения ??? Возможно, вы захотите сделать что-то еще. –

+0

У вас может быть много причин, по которым вы не хотите инициализировать что-то во встроенных. Например. у вас есть большой буфер, который является пустой тратой времени при запуске MCU. Но здесь у меня есть переменная вспышки, и когда MCU стирается, я знаю, что вся область 0xFF. Поэтому нет необходимости инициализировать что-либо. – user1797147

+0

@Eugene Sh. Я уверен, что '{0xFF}' будет инициализировать весь объект, первый с '0xFF', а остальное - с нулевым битом. В C. Частичная инициализация отсутствует. См. Http://stackoverflow.com/q/13104767/2410359 и C11 §6.7.9 21 – chux

ответ

2

Это очистит предупреждение:

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

Однако только первый байт будет 0xff, остальное все 0x00. Чтобы исправить это можно попробовать (с НКУ):

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}; 

Это будет инициализировать все данные 0xff.

reference

+0

Первая строка НЕ ​​НЕТ очистить предупреждение, но второе объяснение, да, иметь смысл. Абсолютная фантастика, огромное спасибо !!! Как я могу дать вам много очков за это? Большое спасибо человеку! – user1797147

+0

GCC классный. Если бы они не делали деревья синтаксического разбора настолько уродливыми и тяжелыми, чтобы их по политическим соображениям. Я пробовал первую строку, и она очистила предупреждение для меня. Однако вы должны делать все фигурные скобки. Удачи. Это был хороший вопрос. – evaitl

+0

Обратите внимание, что форма инициализатора массива, используемая здесь, является расширением GNU.Стандарт C предназначен для одноэлементных указателей, но не для обозначения диапазонов. Конечно, код в целом зависит от других расширений GNU, так что, вероятно, это не имеет значения. –

2

Я должен инициализировать heData с чем-то, что меня устраивает, до тех пор, как все значения будут все (вспышки по умолчанию стирается) 0xFF.

Единственный способ инициализировать объект или любую его часть со значениями, отличными от нуля, - это представить явный инициализатор для этой части. У вас есть умеренно большой объект для инициализации с явными инициализаторами, но поскольку вы хотите инициализировать его повторяющимся шаблоном, препроцессор может вам помочь. Вот один из способов сделать это:

#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}) 
    } 
}; 

Хотя это немного уродливее, чем решение, предложенное в другой ответ, это стандартный C. (Инициализатором часть стандарта, то есть Есть GNU расширения, унаследованные от. вопрос.)

+0

Умный с VA_ARGS тоже, спасибо. – user1797147

Смежные вопросы