Сергей Борщ 119 3 июля, 2007 Опубликовано 3 июля, 2007 · Жалоба Есть многопроцесорная система. Часть кода написана в 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; }; Кто нибудь знает каким образом можно это объединить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 3 июля, 2007 Опубликовано 3 июля, 2007 · Жалоба У каждого компилятора есть предопределенное макро, его описывающее. Ну и дальше по типу: #if defined(__ICCAVR__) // IAR C Compiler #define FLASH_DECLARE(x) __flash x #endif #if defined(__GNUC__) // GNU Compiler #define FLASH_DECLARE(x) x __attribute__((__progmem__)) #endif Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vmp 0 3 июля, 2007 Опубликовано 3 июля, 2007 · Жалоба Совсем красиво не получится. В одном комплекте исходников я видел следующее: #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 генерятся в зависимости от компилятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 3 июля, 2007 Опубликовано 3 июля, 2007 · Жалоба Кто нибудь знает каким образом можно это объединить? Например, вариации по мотивам недавненого обьяснения 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 PACK_on_off.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 3 июля, 2007 Опубликовано 3 июля, 2007 · Жалоба у IAR, в соответсвии со стандартом С99 есть директива _Pragma, которая позволяет запихать #pragma в #define Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 3 июля, 2007 Опубликовано 3 июля, 2007 · Жалоба есть директива _Pragma, которая ... Оператор _Pragma() штука безусловно хорошая, только не для случаев, когда надо писать максимально переносимый код - тут банальный #include вне конкуренции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Спасибо всем за идеи! Оператор _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) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба #include-решение мне не нравится - оно неочевидно, Зато оно не несет никаких следов конкретных компиляторов - вся нюансировка вообще вынесена, не мозолит глаза и не требует вообще никаких правок многочисленных исходникое проекта при добавлении очередного порта. Про независимость от C99 тоже ясно. легко забыть включить завершающий #include, Не аргумент - "забыть" можно многое :) в проекте появляются мелкие файлы, которые собственно исходником не являются. Обычно такие файлы закидываются район системных \SYS а не в каждый проект. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 32 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Зато оно не несет никаких следов конкретных компиляторов - вся нюансировка вообще вынесена, не мозолит глаза и не требует вообще никаких правок многочисленных исходникое проекта при добавлении очередного порта. Про независимость от C99 тоже ясно. Вам _Pragma не нравится, что-ли? Ну, в том смысле, что непереносимая фича. Вообще, это штука давно стандартная и в С, и в С++. Современных компиляторов, которые бы ее не поддерживали, еще поискать. Не аргумент - "забыть" можно многое :) Вполне аргумент - такие места, где можно забыть, надо сводить к минимуму, в пределе к нулю, а не плодить их. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Вам _Pragma не нравится, что-ли? Ну прагма это достаточно нормально, а вот 8 строчек вместо одной c #include, причем многократно повторенные во многих файлах, да и еще с учетом того, что все эти места придется менять при добавлении портов, мне точно не нравятся :( Вполне аргумент - такие места, где можно забыть, надо сводить к минимуму, в пределе к нулю, а не плодить их. В данном случае не аргумент, поскольку количество мест не меняется. Будет закрыватся секция с паковкой #pragma или #include не принципиально. Причем в общем случае #pragma будет не единственной строкой :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Ну прагма это достаточно нормально, а вот 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 в репозитории). В данном случае не аргумент, поскольку количество мест не меняется. Будет закрыватся секция с паковкой #pragma или #include не принципиально. Причем в общем случае #pragma будет не единственной строкой :(Нет, как раз. Тут открывание и закрывание секции в одном макросе. И вместо PACK_STRUCT после объявления в вашем варианте надо писать PACKED в начале и после структуры - ')'. И не нужно думать, что для всех компиляторов кроме GCC играет рояль пара #include (даже если мы забудем PACK_STRUCT), а для GCC они и еще PACK_STRUCT. И если мы забудем закрывающую скобку в моем варианте, компилятор грязно выругается на дальнейший текст, а это уже большой плюс (тут я полностью согласен с dxp). Современных компиляторов, которые бы ее не поддерживали, еще поискать.Как говорится в известной поговорке "свинья всегда грязь найдет". Это я про себя. В смысле нашел - не знаю как _Pragma(), а #pragma pack GCC игнорирует. И толку теперь с этой _Pragma()? :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Стоп. Ну так дело хозяйское. На то, что сделан макрос с подстановкой структуры, я, каюсь, просто не обратил внимания, посему свои слова на счет одинакового количества строк с #include и твоим #define беру обратно :). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 28 сентября, 2009 Опубликовано 28 сентября, 2009 · Жалоба ...если кто-то подскажет как из #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)") попробуйте так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 30 сентября, 2009 Опубликовано 30 сентября, 2009 · Жалоба #define PACKED(pack_val, _struct_) _Pragma("pack (push," #pack_val ")") _struct_; _Pragma("pack (pop)") попробуйте так. Сергей Борщ, получилось? У меня IARа нет, проверить не могу. Но работать должно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 30 сентября, 2009 Опубликовано 30 сентября, 2009 · Жалоба Но работать должно. Не, не совсем так. Вот так надо #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)"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться