|
|
  |
IAR ARM 4.41, Слишком умный :) |
|
|
|
Jul 20 2007, 11:18
|
Знающий
   
Группа: 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 бит, если дело касается каких либо указателей он начинает читать побайтово. Как обойти эту проблему ?, я понимаю что компилер сделал так что код никогда в дата аборт не попадет.
|
|
|
|
|
Jul 20 2007, 11:47
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Цитата Дык ведь pragma pack(1) и говорит компилятору, что нельзя читать словами, поскольку структура в памяти может быть не на границе слова. Уберите pragma pack, а вместо четырёх однобайтовых полей сделайте массив uint8[4]. Pack (1) говорит компилятору у паковать структуру, и если внемательно посмотреть data_1 и data_2 всегда награнице 32 битного слова. Если пак убрать это будет другой пакет совсем  . Отпадает. Цитата Может быть проблем с align ? То есть структуа не расположена на 32 bits boundary ?
... опередили [/code]uint32 my_buff[BUFF_SIZE]; //он тоже выровнен к границе 32 битных слов [code] ?
|
|
|
|
|
Jul 20 2007, 12:05
|

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

|
Цитата(MALLOY2 @ Jul 20 2007, 15:47)  Pack (1) говорит компилятору у паковать структуру, и если внемательно посмотреть data_1 и data_2 всегда награнице 32 битного слова. Если пак убрать это будет другой пакет совсем  . Отпадает. [/code]uint32 my_buff[BUFF_SIZE]; //он тоже выровнен к границе 32 битных слов [code] ? Не совсем так! если в даном случае убрать #pragma pack ничего не изменится, внутри структуры! #pragma pack - отключает выравнивание элементов кратно их размеру и обещго размера структуры кратно большему элементу ( что бы в массиве каждая структура была выравнена). В данном случае все само собой выравнено! и с #pragma pack - будет только тормозить.
|
|
|
|
|
Jul 20 2007, 12:13
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Цитата Не совсем так! если в даном случае убрать #pragma pack ничего не изменится, внутри структуры! #pragma pack - отключает выравнивание элементов кратно их размеру и обещго размера структуры кратно большему элементу ( что бы в массиве каждая структура была выравнена). В данном случае все само собой выравнено! и с #pragma pack - будет только тормозить. Если я уберу pack это будет другой пакет !!! пакеты приходят с другого устройства пакеты имеют как байтовые поля так и 32 битные, но 32 бита всегда на границе, остаются токо об этом расказать компилятору вот токо как ?
|
|
|
|
|
Jul 20 2007, 12:16
|

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

|
Цитата(MALLOY2 @ Jul 20 2007, 16:13)  Если я уберу pack это будет другой пакет !!! пакеты приходят с другого устройства пакеты имеют как байтовые поля так и 32 битные, но 32 бита всегда на границе, остаются токо об этом расказать компилятору вот токо как ? Да не надо ничего говорить! Внутри структуры байты не выраниваются! их размер кратен 1! 16 - бит врыаниваются по 16 бит 32 - бит по 32. если убрать pack - структура будет абсолютно такая же!
|
|
|
|
|
Jul 20 2007, 12:35
|
Знающий
   
Группа: 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] Вопрос стоит не втом чтобы изменить структуры, можно и протокол переделать  , это не проблема, вопрос стоит как заставить компилятор  , и я нашел решение вот так Код 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. Этот вопрос несет спортивный характер
|
|
|
|
|
Jul 20 2007, 12:36
|

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

|
Цитата(MALLOY2 @ Jul 20 2007, 14:18)  Не могу заставить компилятор генерить нужный код. Увы, возможности оптимизации не безграничны  . Путаются. Всегда пытайтесь как можно четче выразить свою мысль. Например так: Код #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
|
|
|
|
|
Jul 20 2007, 13:19
|

Профессионал
    
Группа: Модераторы
Сообщений: 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 битных полей.
|
|
|
|
|
Jul 20 2007, 17:32
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jul 22 2007, 19:28
|

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

|
Цитата(zltigo @ Jul 20 2007, 16:36)  Увы, возможности оптимизации не безграничны  . Путаются. Всегда пытайтесь как можно четче выразить свою мысль. Например так: Код #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
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|