Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: совместное использование исходников IAR и GCC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Сергей Борщ
Есть многопроцесорная система. Часть кода написана в 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
У каждого компилятора есть предопределенное макро, его описывающее. Ну и дальше по типу:

#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
Цитата(Сергей Борщ @ 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 генерятся в зависимости от компилятора.
zltigo
Цитата(Сергей Борщ @ 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
KRS
у IAR, в соответсвии со стандартом С99 есть директива _Pragma, которая позволяет запихать #pragma в #define
zltigo
Цитата(KRS @ Jul 3 2007, 22:22) *
есть директива _Pragma, которая ...

Оператор _Pragma() штука безусловно хорошая, только не для случаев, когда надо писать максимально переносимый код - тут банальный #include вне конкуренции.
Сергей Борщ
Спасибо всем за идеи!
Цитата(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)
zltigo
Цитата(Сергей Борщ @ Jul 4 2007, 10:58) *
#include-решение мне не нравится - оно неочевидно,

Зато оно не несет никаких следов конкретных компиляторов - вся нюансировка вообще вынесена, не мозолит глаза и не требует вообще никаких правок многочисленных исходникое проекта при добавлении очередного порта. Про независимость от C99 тоже ясно.
Цитата
легко забыть включить завершающий #include,

Не аргумент - "забыть" можно многое smile.gif
Цитата
в проекте появляются мелкие файлы, которые собственно исходником не являются.

Обычно такие файлы закидываются район системных \SYS а не в каждый проект.
dxp
Цитата(zltigo @ Jul 4 2007, 18:10) *
Зато оно не несет никаких следов конкретных компиляторов - вся нюансировка вообще вынесена, не мозолит глаза и не требует вообще никаких правок многочисленных исходникое проекта при добавлении очередного порта. Про независимость от C99 тоже ясно.

Вам _Pragma не нравится, что-ли? Ну, в том смысле, что непереносимая фича. Вообще, это штука давно стандартная и в С, и в С++. Современных компиляторов, которые бы ее не поддерживали, еще поискать.

Цитата(zltigo @ Jul 4 2007, 18:10) *
Не аргумент - "забыть" можно многое smile.gif

Вполне аргумент - такие места, где можно забыть, надо сводить к минимуму, в пределе к нулю, а не плодить их.
zltigo
Цитата(dxp @ Jul 4 2007, 14:26) *
Вам _Pragma не нравится, что-ли?

Ну прагма это достаточно нормально, а вот 8 строчек вместо одной c #include, причем многократно повторенные во многих файлах, да и еще с учетом того, что все эти места придется менять при добавлении портов, мне точно не нравятся sad.gif
Цитата
Вполне аргумент - такие места, где можно забыть, надо сводить к минимуму, в пределе к нулю, а не плодить их.

В данном случае не аргумент, поскольку количество мест не меняется. Будет закрыватся секция с паковкой #pragma или #include не принципиально. Причем в общем случае #pragma будет не единственной строкой sad.gif
Сергей Борщ
Цитата(zltigo @ Jul 4 2007, 14:47) *
Ну прагма это достаточно нормально, а вот 8 строчек вместо одной c #include, причем многократно повторенные во многих файлах, да и еще с учетом того, что все эти места придется менять при добавлении портов, мне точно не нравятся sad.gif
Стоп. Но
Код
#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 будет не единственной строкой sad.gif
Нет, как раз. Тут открывание и закрывание секции в одном макросе. И вместо PACK_STRUCT после объявления в вашем варианте надо писать PACKED в начале и после структуры - ')'. И не нужно думать, что для всех компиляторов кроме GCC играет рояль пара #include (даже если мы забудем PACK_STRUCT), а для GCC они и еще PACK_STRUCT. И если мы забудем закрывающую скобку в моем варианте, компилятор грязно выругается на дальнейший текст, а это уже большой плюс (тут я полностью согласен с dxp).

Цитата(dxp @ Jul 4 2007, 14:26) *
Современных компиляторов, которые бы ее не поддерживали, еще поискать.
Как говорится в известной поговорке "свинья всегда грязь найдет". Это я про себя. В смысле нашел - не знаю как _Pragma(), а #pragma pack GCC игнорирует. И толку теперь с этой _Pragma()? laughing.gif
zltigo
Цитата(Сергей Борщ @ Jul 4 2007, 18:19) *
Стоп.

Ну так дело хозяйское. На то, что сделан макрос с подстановкой структуры, я, каюсь, просто не обратил внимания, посему свои слова на счет одинакового количества строк с #include и твоим #define беру обратно smile.gif.
Petka
Цитата(Сергей Борщ @ 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)")

попробуйте так.
Petka
Цитата(Petka @ Sep 28 2009, 15:59) *
Код
#define PACKED(pack_val, _struct_)          _Pragma("pack (push," #pack_val ")") _struct_; _Pragma("pack (pop)")

попробуйте так.


Сергей Борщ, получилось? У меня IARа нет, проверить не могу. Но работать должно.
Rst7
Цитата
Но работать должно.


Не, не совсем так. Вот так надо
Код
#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)");
Petka
Цитата(Rst7 @ Sep 30 2009, 12:44) *
Не, не совсем так....

Именно так. Согласно С99 пункту 6.4.5 "String literals", раздел 7, подряд идущие строки клеятся в одну. "12" "3" эквивалентно "123". Делает ли так IAR не знаю.
Хотя ваш способ понятнее.
Rst7
Цитата
Хотя ваш способ понятнее.


Более того, мой способ работает, в отличии от Вашего wink.gif Я проверил - внутри _Pragma у IAR'а строки не склеиваются.
Petka
Цитата(Rst7 @ Sep 30 2009, 14:29) *
Более того, мой способ работает, в отличии от Вашего wink.gif Я проверил - внутри _Pragma у IAR'а строки не склеиваются.

Это и надо было проверить. Можете проверить, а снаружи прагмы строки клеятся или тоже нет?
Rst7
Цитата
Можете проверить, а снаружи прагмы строки клеятся или тоже нет?


Конечно клеит. Это только прагма такая особенная.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.