реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> совместное использование исходников IAR и GCC, как быть с #pragma pack?
Сергей Борщ
сообщение Jul 3 2007, 13:53
Сообщение #1


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jul 3 2007, 14:40
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



У каждого компилятора есть предопределенное макро, его описывающее. Ну и дальше по типу:

#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
Go to the top of the page
 
+Quote Post
vmp
сообщение Jul 3 2007, 14:45
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 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 генерятся в зависимости от компилятора.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 3 2007, 17:35
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 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

Прикрепленные файлы
Прикрепленный файл  PACK_on_off.rar ( 462 байт ) Кол-во скачиваний: 145
 


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
KRS
сообщение Jul 3 2007, 19:22
Сообщение #5


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



у IAR, в соответсвии со стандартом С99 есть директива _Pragma, которая позволяет запихать #pragma в #define
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 3 2007, 19:53
Сообщение #6


Гуру
******

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



Цитата(KRS @ Jul 3 2007, 22:22) *
есть директива _Pragma, которая ...

Оператор _Pragma() штука безусловно хорошая, только не для случаев, когда надо писать максимально переносимый код - тут банальный #include вне конкуренции.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 4 2007, 07:58
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 4 2007, 11:10
Сообщение #8


Гуру
******

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



Цитата(Сергей Борщ @ Jul 4 2007, 10:58) *
#include-решение мне не нравится - оно неочевидно,

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

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

Обычно такие файлы закидываются район системных \SYS а не в каждый проект.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
dxp
сообщение Jul 4 2007, 11:26
Сообщение #9


Adept
******

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



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

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

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

Вполне аргумент - такие места, где можно забыть, надо сводить к минимуму, в пределе к нулю, а не плодить их.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 4 2007, 11:47
Сообщение #10


Гуру
******

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



Цитата(dxp @ Jul 4 2007, 14:26) *
Вам _Pragma не нравится, что-ли?

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

В данном случае не аргумент, поскольку количество мест не меняется. Будет закрыватся секция с паковкой #pragma или #include не принципиально. Причем в общем случае #pragma будет не единственной строкой sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 4 2007, 15:19
Сообщение #11


Гуру
******

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



Цитата(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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 4 2007, 16:19
Сообщение #12


Гуру
******

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



Цитата(Сергей Борщ @ Jul 4 2007, 18:19) *
Стоп.

Ну так дело хозяйское. На то, что сделан макрос с подстановкой структуры, я, каюсь, просто не обратил внимания, посему свои слова на счет одинакового количества строк с #include и твоим #define беру обратно smile.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 28 2009, 11:59
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 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)")

попробуйте так.
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 30 2009, 07:58
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 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а нет, проверить не могу. Но работать должно.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Sep 30 2009, 08:44
Сообщение #15


Йа моск ;)
******

Группа: Модераторы
Сообщений: 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)");


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 17:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.0154 секунд с 7
ELECTRONIX ©2004-2016