|
совместное использование исходников IAR и GCC, как быть с #pragma pack? |
|
|
|
Jul 3 2007, 13:53
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Есть многопроцесорная система. Часть кода написана в IAR. Часть кода надо написать на WinAVR. Имеется несколько заголовочных файлов, описывающие нечто общее для всей системы, например структуры, которыми идет обмен по системной шине. Поскольку в системе используются и ARM и AVR приходится использовать упакованные структуры. Но этим двум компиляторам требуется описывать упаковку по-разному. Итого имеем: Код IAR: #pragma pack (push,1) struct tmp_t { uint8_t A; uint16_t B; }; #pragma pack (pop)
WinAVR: struct tmp_t { uint8_t A; uint16_t B; }__attribute__((__packed__, __aligned__ (1))); или struct tmp_t __attribute__((__packed__, __aligned__ (1))); struct tmp_t { uint8_t A; uint16_t B; }; Кто нибудь знает каким образом можно это объединить?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 3 2007, 14:45
|

Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070

|
Цитата(Сергей Борщ @ Jul 3 2007, 17:53)  Совсем красиво не получится. В одном комплекте исходников я видел следующее: Код #if __packed_pragma #pragma pack(1) #endif
typedef __packed struct { int aaa; char bbb; } __packed_gnu T_AB;
#if __packed_pragma #pragma pack() #endif Дефайны для __packed_pragma, __packed и __packed_gnu генерятся в зависимости от компилятора.
|
|
|
|
|
Jul 3 2007, 17:35
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jul 3 2007, 16:53)  Кто нибудь знает каким образом можно это объединить? Например, вариации по мотивам недавненого обьяснения http://electronix.ru/forum/index.php?showt...321&hl=packпаковки структур в lwIP: Код #include packon struct tmp_t { uint8_t A; uint16_t B; }PACK_STRUCT; #include packoff
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 4 2007, 07:58
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Спасибо всем за идеи! Цитата(zltigo @ Jul 3 2007, 22:53)  Оператор _Pragma() штука безусловно хорошая, только не для случаев, когда надо писать максимально переносимый код - тут банальный #include вне конкуренции. #include-решение мне не нравится - оно неочевидно, легко забыть включить завершающий #include, в проекте появляются мелкие файлы, которые собственно исходником не являются. Ваши советы и макрос ATOMIC_CODE имени ReAl натолкнули меня на такое решение: Код #if defined( __GNUC__ ) #define PACKED(_struct_) \ _struct_ __attribute__((__packed__, __aligned__(1))); #elif defined( __IAR_SYSTEMS_ICC__ ) #define PACKED(_struct_) \ _Pragma("pack (push,1)") _struct_; _Pragma("pack (pop)") #endif
PACKED( struct test_t { uint8_t A; uint16_t B; } ) Что-то подобное я пытался сделать перед тем, как задать вопрос, но я хотел дополнительно передавать параметр выравнивания, и если для GCC мне легко удалось его засунуть в __aligned__(N), то ИАР требует чтобы параметр _Pragma() был в кавычках и вот тут я застрял. А ваши ответы натолкнули на мысль, что нужны всего две упаковки - "побайтная" и "по умолчанию = без упаковки". Хотя если кто-то подскажет как из #define PACKED(pack_val, _struct_) вставить значение pack_val в _Pragma("pack (push,1)") вместо '1', буду очень благода. P.S. макрос имени ReAl выглядит так: Код #define ATOMIC_CODE(_code_) do { \ uint8_t sreg = SREG; \ __disable_interrupt(); \ { _code_ } \ SREG = sreg; \ } while(0)
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 4 2007, 11:10
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jul 4 2007, 10:58)  #include-решение мне не нравится - оно неочевидно, Зато оно не несет никаких следов конкретных компиляторов - вся нюансировка вообще вынесена, не мозолит глаза и не требует вообще никаких правок многочисленных исходникое проекта при добавлении очередного порта. Про независимость от C99 тоже ясно. Цитата легко забыть включить завершающий #include, Не аргумент - "забыть" можно многое  Цитата в проекте появляются мелкие файлы, которые собственно исходником не являются. Обычно такие файлы закидываются район системных \SYS а не в каждый проект.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 4 2007, 11:26
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(zltigo @ Jul 4 2007, 18:10)  Зато оно не несет никаких следов конкретных компиляторов - вся нюансировка вообще вынесена, не мозолит глаза и не требует вообще никаких правок многочисленных исходникое проекта при добавлении очередного порта. Про независимость от C99 тоже ясно. Вам _Pragma не нравится, что-ли? Ну, в том смысле, что непереносимая фича. Вообще, это штука давно стандартная и в С, и в С++. Современных компиляторов, которые бы ее не поддерживали, еще поискать. Цитата(zltigo @ Jul 4 2007, 18:10)  Не аргумент - "забыть" можно многое  Вполне аргумент - такие места, где можно забыть, надо сводить к минимуму, в пределе к нулю, а не плодить их.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jul 4 2007, 11:47
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(dxp @ Jul 4 2007, 14:26)  Вам _Pragma не нравится, что-ли? Ну прагма это достаточно нормально, а вот 8 строчек вместо одной c #include, причем многократно повторенные во многих файлах, да и еще с учетом того, что все эти места придется менять при добавлении портов, мне точно не нравятся  Цитата Вполне аргумент - такие места, где можно забыть, надо сводить к минимуму, в пределе к нулю, а не плодить их. В данном случае не аргумент, поскольку количество мест не меняется. Будет закрыватся секция с паковкой #pragma или #include не принципиально. Причем в общем случае #pragma будет не единственной строкой
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 4 2007, 15:19
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(zltigo @ Jul 4 2007, 14:47)  Ну прагма это достаточно нормально, а вот 8 строчек вместо одной c #include, причем многократно повторенные во многих файлах, да и еще с учетом того, что все эти места придется менять при добавлении портов, мне точно не нравятся  Стоп. Но Код #if defined( __GNUC__ ) #define PACKED(_struct_) \ _struct_ __attribute__((__packed__, __aligned__(1))); #elif defined( __IAR_SYSTEMS_ICC__ ) #define PACKED(_struct_) \ _Pragma("pack (push,1)") _struct_; _Pragma("pack (pop)") #endif точно также вносится в один #include-файл в котором и так живет куча полезных вещей. Только этот файл и правится при добавлении портов. Этот файл имеет право жить в /SYS (хотя в этом случае начинаются проблемы с системой контроля версий, но это не принципиально - пусть будет папка /sys в репозитории). Цитата(zltigo @ Jul 4 2007, 14:47)  В данном случае не аргумент, поскольку количество мест не меняется. Будет закрыватся секция с паковкой #pragma или #include не принципиально. Причем в общем случае #pragma будет не единственной строкой  Нет, как раз. Тут открывание и закрывание секции в одном макросе. И вместо PACK_STRUCT после объявления в вашем варианте надо писать PACKED в начале и после структуры - ')'. И не нужно думать, что для всех компиляторов кроме GCC играет рояль пара #include (даже если мы забудем PACK_STRUCT), а для GCC они и еще PACK_STRUCT. И если мы забудем закрывающую скобку в моем варианте, компилятор грязно выругается на дальнейший текст, а это уже большой плюс (тут я полностью согласен с dxp). Цитата(dxp @ Jul 4 2007, 14:26)  Современных компиляторов, которые бы ее не поддерживали, еще поискать. Как говорится в известной поговорке "свинья всегда грязь найдет". Это я про себя. В смысле нашел - не знаю как _Pragma(), а #pragma pack GCC игнорирует. И толку теперь с этой _Pragma()?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 4 2007, 16:19
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jul 4 2007, 18:19)  Стоп. Ну так дело хозяйское. На то, что сделан макрос с подстановкой структуры, я, каюсь, просто не обратил внимания, посему свои слова на счет одинакового количества строк с #include и твоим #define беру обратно  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 28 2009, 11:59
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(Сергей Борщ @ Jul 4 2007, 11:58)  ...если кто-то подскажет как из #define PACKED(pack_val, _struct_) вставить значение pack_val в _Pragma("pack (push,1)") вместо '1', буду очень благодарен. Код #define PACKED(pack_val, _struct_) _Pragma("pack (push," #pack_val ")") _struct_; _Pragma("pack (pop)") попробуйте так.
|
|
|
|
|
Sep 30 2009, 07:58
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(Petka @ Sep 28 2009, 15:59)  Код #define PACKED(pack_val, _struct_) _Pragma("pack (push," #pack_val ")") _struct_; _Pragma("pack (pop)") попробуйте так. Сергей Борщ, получилось? У меня IARа нет, проверить не могу. Но работать должно.
|
|
|
|
|
Sep 30 2009, 08:44
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Но работать должно. Не, не совсем так. Вот так надо Код #define PACKED_QUOTED(V1) #V1 #define PACKED(pack_val, _struct_) _Pragma(PACKED_QUOTED(pack(push,pack_val))); _struct_; _Pragma("pack (pop)")
PACKED(1, typedef struct { char a; char b; }C ); И результат Код _Pragma("pack(push,1)"); typedef struct { char a; char b; }C; _Pragma("pack (pop)");
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|