Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR ARM 4.41
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
MALLOY2
Не могу заставить компилятор генерить нужный код.
Есть такая структура
Код
#pragma pack(1)
typedef  
          {
            uint8     a8_0;
            uint8     a8_1;
            uint8     a8_2;
            uint8     a8_3;
            uint32   data_1;    
            uint32   data_2;
          } rtp_heder_t;


далее имеем массив 32 битных значений.

Код
uint32 my_buff[BUFF_SIZE];   //он тоже выровнен к границе 32 битных слов


далее идет функция
Код
void rtp_process(uint32 data)
{
   rtp_heder_t *ptr;                        //указатель на структуру  

   ptr = (rtp_heder_t*)&my_buff;    //берем указатель буфера ввода
  
   if (ptr->data_1 == data) ...         //вот здесь и порылась собака, сравнение происходит побайтово.  

}


Если my_buf объявить как rtp_heder_t тогда при сравнении используется чтение 32 бит, если дело касается каких либо указателей он начинает читать побайтово. Как обойти эту проблему ?, я понимаю что компилер сделал так что код никогда в дата аборт не попадет.
scifi
Дык ведь pragma pack(1) и говорит компилятору, что нельзя читать словами, поскольку структура в памяти может быть не на границе слова. Уберите pragma pack, а вместо четырёх однобайтовых полей сделайте массив uint8[4].
_artem_
Может быть проблем с align ? То есть структуа не расположена на 32 bits boundary ?

... опередили
MALLOY2
Цитата
Дык ведь pragma pack(1) и говорит компилятору, что нельзя читать словами, поскольку структура в памяти может быть не на границе слова. Уберите pragma pack, а вместо четырёх однобайтовых полей сделайте массив uint8[4].


Pack (1) говорит компилятору у паковать структуру, и если внемательно посмотреть data_1 и data_2 всегда награнице 32 битного слова. Если пак убрать это будет другой пакет совсем smile.gif. Отпадает.


Цитата
Может быть проблем с align ? То есть структуа не расположена на 32 bits boundary ?

... опередили


[/code]uint32 my_buff[BUFF_SIZE]; //он тоже выровнен к границе 32 битных слов [code]

?
KRS
Цитата(MALLOY2 @ Jul 20 2007, 15:47) *
Pack (1) говорит компилятору у паковать структуру, и если внемательно посмотреть data_1 и data_2 всегда награнице 32 битного слова. Если пак убрать это будет другой пакет совсем smile.gif. Отпадает.
[/code]uint32 my_buff[BUFF_SIZE]; //он тоже выровнен к границе 32 битных слов [code]

?


Не совсем так! если в даном случае убрать #pragma pack ничего не изменится, внутри структуры!
#pragma pack - отключает выравнивание элементов кратно их размеру и обещго размера структуры кратно большему элементу ( что бы в массиве каждая структура была выравнена).
В данном случае все само собой выравнено!
и с #pragma pack - будет только тормозить.
MALLOY2
Цитата
Не совсем так! если в даном случае убрать #pragma pack ничего не изменится, внутри структуры!
#pragma pack - отключает выравнивание элементов кратно их размеру и обещго размера структуры кратно большему элементу ( что бы в массиве каждая структура была выравнена).
В данном случае все само собой выравнено!
и с #pragma pack - будет только тормозить.


Если я уберу pack это будет другой пакет !!! пакеты приходят с другого устройства пакеты имеют как байтовые поля так и 32 битные, но 32 бита всегда на границе, остаются токо об этом расказать компилятору вот токо как ?
KRS
Цитата(MALLOY2 @ Jul 20 2007, 16:13) *
Если я уберу pack это будет другой пакет !!! пакеты приходят с другого устройства пакеты имеют как байтовые поля так и 32 битные, но 32 бита всегда на границе, остаются токо об этом расказать компилятору вот токо как ?

Да не надо ничего говорить!
Внутри структуры байты не выраниваются! их размер кратен 1!
16 - бит врыаниваются по 16 бит
32 - бит по 32.
если убрать pack - структура будет абсолютно такая же!
IgorKossak
В определении структуры забыли написать слово struct.
Если конечно в этом дело.
MALLOY2
Цитата
Да не надо ничего говорить!
Внутри структуры байты не выраниваются! их размер кратен 1!
16 - бит врыаниваются по 16 бит
32 - бит по 32.
если убрать pack - структура будет абсолютно такая же!


Я наверное многих ввл в заблуждение стуруктурой
Код
#pragma pack(1)
typedef  
          {
            uint8     a8_0;
            uint8     a8_1;
            uint8     a8_2;
            uint8     a8_3;
            uint32   data_1;    
            uint32   data_2;
          } rtp_heder_t;


Эта структура просто как пример, давайте расмотримтакую структуру, она более наглядно докажет что pack убрать нельзя.
typedef
{
uint8 a8_0;
uint16 x;
uint8 a8_1;
uint32 data_1;
uint32 data_2;
} rtp_heder_t;

[/code]

Вопрос стоит не втом чтобы изменить структуры, можно и протокол переделать smile.gif, это не проблема, вопрос стоит как заставить компилятор smile.gif, и я нашел решение smile.gif

вот так
Код
   rtp_heder_t *ptr;                        //указатель на структуру    
   uint32 *t;                                   //дополнительная переменная без нее никак

   ptr = (rtp_heder_t*)&my_buff;    //берем указатель буфера ввода
   t = (uint32*)(&ptr->data_1);      
  
   if (*t == data) ...         //вот теперь работает как надо


Приэтом компилятор выдал варниг
Warning[Pa039]: use of address of unaligned structure member

P.S. Этот вопрос несет спортивный характер smile.gif
zltigo
Цитата(MALLOY2 @ Jul 20 2007, 14:18) *
Не могу заставить компилятор генерить нужный код.


Увы, возможности оптимизации не безграничны sad.gif. Путаются. Всегда пытайтесь как можно четче выразить свою мысль. Например так:
Код
#pragma pack( push, 1)
typedef  struct aaaa_t {

          {    uint8     a8_0;
            uint8     a8_1;
            uint8     a8_2;
            uint8     a8_3;
          } aaaa_t;

#pragma pack( pop )
          {
            aaaa_t     aaaa;
            uint32   data_1;    
            uint32   data_2;
          } rtp_heder_t;

Сработает.
KRS
Цитата(MALLOY2 @ Jul 20 2007, 16:35) *
Эта структура просто как пример, давайте расмотримтакую структуру, она более наглядно докажет что pack убрать нельзя.
Код
typedef  
          {
            uint8     a8_0;
            uint16   x;
            uint8     a8_1;
            uint32   data_1;    
            uint32   data_2;
          } rtp_heder_t;

Да здесь pack убирать нельзя.
Но можно разбить x на два байта uint8_t xl, xh - и обращаться через макросы.
Либо определить 2 структуры одну packet, другую обычную но без 16 битных полей.
Сергей Борщ
Цитата(KRS @ Jul 20 2007, 16:19) *
Да здесь pack убирать нельзя.
Почему?
Код
typedef  struct
    {
        #pragma pack(push, 1)
        struct
        {
            uint8     a8_0;
            uint16   x;
            uint8     a8_1;
        };
        #pragma pack(pop)
        uint32   data_1;    
        uint32   data_2;
    } rtp_heder_t;
mdmitry
Возможно в структуре поменять поля: поставить первыми 32 битные, а далее 8 битные. Выравнивание, кажется, должно измениться.
KRS
Цитата(mdmitry @ Jul 21 2007, 00:07) *
Возможно в структуре поменять поля: поставить первыми 32 битные, а далее 8 битные. Выравнивание, кажется, должно измениться.

В данном случае менять поля нельзя! Это же опсание протокола обмена.
lebiga
Цитата(zltigo @ Jul 20 2007, 16:36) *
Увы, возможности оптимизации не безграничны sad.gif. Путаются. Всегда пытайтесь как можно четче выразить свою мысль. Например так:
Код
#pragma pack( push, 1)
typedef  struct aaaa_t {

          {    uint8     a8_0;
            uint8     a8_1;
            uint8     a8_2;
            uint8     a8_3;
          } aaaa_t;

#pragma pack( pop )
          {
            aaaa_t     aaaa;
            uint32   data_1;    
            uint32   data_2;
          } rtp_heder_t;

Сработает.


Делай, как zltigo - это самое оптимальное. Если не хочется править программу изменяя переменные типа rtp_heder_t.aaaa_t.a8_0 - переопредели через #define
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.