Перейти к содержанию
    

Выравнивание при доступе к полям структур в Code Composer Studio v. 3.3

Имеется следующий код на C++ для 6000-ков, который считывает некоторую структуру из бинарного файла. После загрузки данных при доступе к полям структуры выясняется, что они выравниваются на 4 байта.

typedef unsigned short WORD; //16-bit
typedef unsigned int DWORD; //32-bit

//The BITMAPFILEHEADER structure contains information about the type, size, and layout of a file that contains a DIB.
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

BITMAPFILEHEADER bmfh;

int O1=(char*)&bmfh.bfType-(char*)&bmfh;
int O2=(char*)&bmfh.bfSize-(char*)&bmfh;
int O3=sizeof(bmfh.bfType);
int O4=sizeof(WORD);
int O5=sizeof(BITMAPFILEHEADER);
int O6=sizeof(bmfh);

Значения смещений будут следующими:

O1==0

O2==4

O3==2

O4==2

O5==16

O6==16

По идее значение O2 должно быть равным 2, а O5 и O6 равными 14. Как сделать, чтобы выравнивание при доступе к элементам структуры было правильным?

Пробовал через команду препроцессора STRUCT_ALIGN например следующим образом:

#pragma STRUCT_ALIGN(128);
typedef struct st_tag
{
int a;
short b;
} st_typedef;

но компилятор выдаёт предупреждение warning: unrecognized #pragma. Как быть в этой ситуации?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#pragma STRUCT_ALIGN(128);
Не знаю CCS, но в большом количестве компиляторов используется #pragma pack(). Может и тут так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не знаю CCS, но в большом количестве компиляторов используется #pragma pack(). Может и тут так?

Нет в CCS такая конструкция не работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пробуй так:

 

typedef __packed struct st_tag {

int a;

short b;

} st_typedef;

 

на компиляторе cc68k00 мне помогло, там тоже нет

#pragma pack()

 

Имеется следующий код на C++ для 6000-ков

А что за компилятор такой?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пробуй так:

 

typedef __packed struct st_tag {

int a;

short b;

} st_typedef;

 

на компиляторе cc68k00 мне помогло, там тоже нет

#pragma pack()

Не работает.

А что за компилятор такой?

Точно не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это, похоже, непоборимо.

Вот что по этому поводу пишет хэлп композера (правда, версии 3.1) (поиск -> structures and arrays):

 

Structures always reserve memory in multiples of the size of the largest element type. For example, if a structure contains an int, unsigned int, or float, a multiple of 4 bytes of storage is reserved in memory. Members of structures are stored in the same manner as if they were individual objects.

 

STRUCT_ALIGN - это немного не то что нужно:

The STRUCT_ALIGN pragma is similar to DATA_ALIGN, but it can be applied to a structure, union type, or typedef and is inherited by any symbol created from that type. The STRUCT_ALIGN pragma is supported only in C.

Т.е. выравниваются все переменные объявленного типа целиком, а не элементы структуры.

 

А жалуется, может быть, потому что объявление немного другое:

typedef struct st_tag

{

int a;

short b;

} st_typedef;

#pragma STRUCT_ALIGN (st_tag, 128);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это, похоже, непоборимо.

Вот что по этому поводу пишет хэлп композера (правда, версии 3.1) (поиск -> structures and arrays):

 

Structures always reserve memory in multiples of the size of the largest element type. For example, if a structure contains an int, unsigned int, or float, a multiple of 4 bytes of storage is reserved in memory. Members of structures are stored in the same manner as if they were individual objects.

 

STRUCT_ALIGN - это немного не то что нужно:

The STRUCT_ALIGN pragma is similar to DATA_ALIGN, but it can be applied to a structure, union type, or typedef and is inherited by any symbol created from that type. The STRUCT_ALIGN pragma is supported only in C.

Т.е. выравниваются все переменные объявленного типа целиком, а не элементы структуры.

Т. е. получается, что если в структуре имеются элементы размером 4 байта, то даже если в структуре имеются элементы размером 2 байта, то они уже всегда будут выравниваться по верхней границе 4 байт. Как-то это не правильно сделано в CCS.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

packed struct техас не поддерживает в принципе - говорят что этого нет в стандарте, на нужды людей им как обычно наплевать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот ответ от службы поддержки TI от 13 марта 2008 г.

 

"...Well, yes, what you have reported to us is correct. In fact there is a problem with the Struct_Align pragma. This is actually a CCS bug and has already been reported to the concerned developers. In fact there are bugs that have been filed for this.

The bug number is SDSCM00008809. This is being worked upon by the developers and we hope to get this rectified as soon as possible. That is the latest update that I can give for the moment."

 

Так что, они об этой проблеме знают и стараются ее решить. Как скоро - неизвестно. Нам остается только ждать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

>Как сделать, чтобы выравнивание при доступе к элементам структуры было правильным?

 

Располагать поля нужно по увеличению размера. Но даже в этом случае адрес следующей структуры будет выровнен на 4 байта.

Изменено пользователем Ghost2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прямо скажу, что в 6000 невыровненные данные не поддерживаются вообще. Т.е. 4-байтный int ВСЕГДА будет выровнен по 4-байтной границе. Иного не поддерживает ядро процессора. Функция чтения 4-байтного int'а LDW использует адрес таким образом, что 2 последних бита его ВСЕГДА нули. Аналогично и для 2 байт.

Невыровненное чтение/запись появились только в 6400-й серии. Там есть даже intrinsic'и для использования такого чтения/записи в С/С++. Но использование невыровненных данных в структурах невозможно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть получается, что считывать данные таким методом:

 

    typedef union
    {
          Uint8     Byte[4];
          Uint32      Word;
    } Uword; 


   Uword Data;

   while (!MCBSP_xrdy(hMcbsp));       
    MCBSP_write(hMcbsp,0x00);
    while (!MCBSP_rrdy(hMcbsp));
    Data.Byte[1] = MCBSP_read(hMcbsp);
    while (!MCBSP_xrdy(hMcbsp));          
    MCBSP_write(hMcbsp,0x00);
    while (!MCBSP_rrdy(hMcbsp));
    Data.Byte[0] = MCBSP_read(hMcbsp);
    return (Data.Word  <<= 1);

в CCS нельзя?

А как быть, если надо считать по SPI младший и старший разряд, а затем иметь доступ ко всему слову?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...