Макрос для перестановки составного инициализатора в C

#c #gcc #macros

Вопрос:

Введение

Я верю, что ошибок можно избежать, назначив значения регистров микроконтроллера в том же порядке, в каком они были описаны в спецификации производителя. Я пришел к следующему решению:

 struct myBits {  uint32_t b00 : 1;  uint32_t b01 : 1;  uint32_t b02 : 1;  ...  uint32_t b30 : 1;  uint32_t b31 : 1; };   // PIOB-gt; offset: PIO_CODR // 0x400E1000U 0x00000034U (*(volatile uint32_t*)0x400E1034U) = *(uint32_t*)amp;(struct myBits) { // -------------------------------------------------------------------------------------------------- /*| B31 | B30 | B29 | B28 | B27 | B26 | B25 | B24 |*/ .b31= 0 ,.b30= 0 ,.b29= 0 ,.b28= 0 ,.b27= 0 ,.b26= 0 ,.b25= 0 ,.b24= 0 , // -------------------------------------------------------------------------------------------------- /*| B23 | B22 | B21 | B20 | B19 | B18 | B17 | B16 |*/ .b23= 0 ,.b22= 0 ,.b21= 0 ,.b20= 0 ,.b19= 0 ,.b18= 0 ,.b17= 0 ,.b16= 0 , // -------------------------------------------------------------------------------------------------- /*| B15 | B14 | B13 | B12 | B11 | B10 | B09 | B08 |*/ .b15= 0 ,.b14= 0 ,.b13= 0 ,.b12= 0 ,.b11= 0 ,.b10= 0 ,.b09= 0 ,.b08= 0 , // -------------------------------------------------------------------------------------------------- /*| B07 | B06 | B05 | B04 | B03 | B02 | B01 | P00 |*/ .b07= 0 ,.b06= 0 ,.b05= 0 ,.b04= 0 ,.b03= 0 ,.b02= 0 ,.b01= 0 ,.b00= 0 };  

проблема

Мне бы хотелось иметь макрос для переключения значений структуры в составном назначении, чтобы устранить необходимость в обозначениях:

 // PIOB-gt; offset: PIO_CODR // 0x400E1000U 0x00000034U (*(volatile uint32_t*)0x400E1034U) = *(uint32_t*)amp;(struct myBits) desiredMacro ({ // -------------------------------------------------------------------------------------------------- /*| B31 | B30 | B29 | B28 | B27 | B26 | B25 | B24 |*/  0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , // -------------------------------------------------------------------------------------------------- /*| B23 | B22 | B21 | B20 | B19 | B18 | B17 | B16 |*/  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // -------------------------------------------------------------------------------------------------- /*| B15 | B14 | B13 | B12 | B11 | B10 | B09 | B08 |*/  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // -------------------------------------------------------------------------------------------------- /*| B07 | B06 | B05 | B04 | B03 | B02 | B01 | P00 |*/  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 });  

Возможно ли это?

Заранее спасибо. Надеюсь, мое искусство ASCII вдохновит сообщество.

Комментарии:

1. При выполнении задания без макроса я получаю БИТ 31 как наименее значимую двоичную цифру. Я перепроверю, что я не указал нерабочее решение, заказав структуру наоборот, извините, если это так. Я хочу, чтобы первый член структуры был самой значимой цифрой в назначении uint32_t.

2. О, я понимаю, извините за это, я неправильно понял заказ.

3. Без проблем. Я весь день менял порядок структуры, так что это могла быть моя вина. Скомпилировал код для подтверждения, и, похоже, расположение вопросов было в порядке.

4. Если вы готовы немного изменить синтаксис, вы можете сделать #define REVERSE(b0, b1, ..., b31) b31, b30, ..., b0 это и тогда *ptr = *(uint32_t)amp;(struct myBits) { REVERSE( 0,0,1,...) }; . Обратите внимание, что каламбур вашего типа является отдельной проблемой, поскольку он нарушает строгое сглаживание. Так будет лучше *(volatile struct myBits *)0xdeadbeef = (struct myBits) { ... } .

Ответ №1:

решение

Пересмотрел одну из моих предыдущих попыток макросъемки из-за предложенного Нейтом Элдриджем решения. На этот раз я написал макрос правильно и сработал.

 #define invertMacro(b31,b30,b29,b28,b27,b26,b25,b24,b23,b22,b21,b20,b19,b18,b17,b16,b15,b14,b13,b12,b11,b10,b09,b08,b07,b06,b05,b04,b03,b02,b01,b00) b00,b01,b02,b03,b04,b05,b06,b07,b08,b09,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20,b21,b22,b23,b24,b25,b26,b27,b28,b29,b30,b31  // PIOB-gt; offset: PIO_CODR // 0x400E1000U 0x00000034U (*(volatile uint32_t*)0x400E1034U) = *(uint32_t*)amp;(struct myBits) { invertMacro ( // -------------------------------------------------------------------------------------------------- /*| B31 | B30 | B29 | B28 | B27 | B26 | B25 | B24 |*/  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // -------------------------------------------------------------------------------------------------- /*| B23 | B22 | B21 | B20 | B19 | B18 | B17 | B16 |*/  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // -------------------------------------------------------------------------------------------------- /*| B15 | B14 | B13 | B12 | B11 | B10 | B09 | B08 |*/  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // -------------------------------------------------------------------------------------------------- /*| B07 | B06 | B05 | B04 | B03 | B02 | B01 | P00 |*/  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )};  

При копировании этого кода обратите внимание на его предложение избегать нарушения строгого сглаживания при каламбурах.