#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 )};
При копировании этого кода обратите внимание на его предложение избегать нарушения строгого сглаживания при каламбурах.