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

 
 
 
Reply to this topicStart new topic
> IAR ARM 4.41, Слишком умный :)
MALLOY2
сообщение Jul 20 2007, 11:18
Сообщение #1


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Не могу заставить компилятор генерить нужный код.
Есть такая структура
Код
#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 бит, если дело касается каких либо указателей он начинает читать побайтово. Как обойти эту проблему ?, я понимаю что компилер сделал так что код никогда в дата аборт не попадет.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 20 2007, 11:26
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Дык ведь pragma pack(1) и говорит компилятору, что нельзя читать словами, поскольку структура в памяти может быть не на границе слова. Уберите pragma pack, а вместо четырёх однобайтовых полей сделайте массив uint8[4].
Go to the top of the page
 
+Quote Post
_artem_
сообщение Jul 20 2007, 11:26
Сообщение #3


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



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

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


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jul 20 2007, 11:47
Сообщение #4


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Цитата
Дык ведь 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]

?
Go to the top of the page
 
+Quote Post
KRS
сообщение Jul 20 2007, 12:05
Сообщение #5


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

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



Цитата(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 - будет только тормозить.
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jul 20 2007, 12:13
Сообщение #6


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



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


Если я уберу pack это будет другой пакет !!! пакеты приходят с другого устройства пакеты имеют как байтовые поля так и 32 битные, но 32 бита всегда на границе, остаются токо об этом расказать компилятору вот токо как ?
Go to the top of the page
 
+Quote Post
KRS
сообщение Jul 20 2007, 12:16
Сообщение #7


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

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



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

Да не надо ничего говорить!
Внутри структуры байты не выраниваются! их размер кратен 1!
16 - бит врыаниваются по 16 бит
32 - бит по 32.
если убрать pack - структура будет абсолютно такая же!
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jul 20 2007, 12:28
Сообщение #8


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



В определении структуры забыли написать слово struct.
Если конечно в этом дело.
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jul 20 2007, 12:35
Сообщение #9


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Цитата
Да не надо ничего говорить!
Внутри структуры байты не выраниваются! их размер кратен 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
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 20 2007, 12:36
Сообщение #10


Гуру
******

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



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

Сработает.


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


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

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



Цитата(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 битных полей.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 20 2007, 17:32
Сообщение #12


Гуру
******

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



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


--------------------
На любой вопрос даю любой ответ
"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
mdmitry
сообщение Jul 20 2007, 20:07
Сообщение #13


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Возможно в структуре поменять поля: поставить первыми 32 битные, а далее 8 битные. Выравнивание, кажется, должно измениться.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
KRS
сообщение Jul 22 2007, 09:43
Сообщение #14


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

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



Цитата(mdmitry @ Jul 21 2007, 00:07) *
Возможно в структуре поменять поля: поставить первыми 32 битные, а далее 8 битные. Выравнивание, кажется, должно измениться.

В данном случае менять поля нельзя! Это же опсание протокола обмена.
Go to the top of the page
 
+Quote Post
lebiga
сообщение Jul 22 2007, 19:28
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 22-06-06
Из: Киев
Пользователь №: 18 292



Цитата(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
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 10:12
Рейтинг@Mail.ru


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