Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Выравнивание при доступе к полям структур в Code Composer Studio v. 3.3
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
rifch
Имеется следующий код на 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. Как быть в этой ситуации?
Сергей Борщ
Цитата(rifch @ Sep 4 2007, 15:47) *
#pragma STRUCT_ALIGN(128);
Не знаю CCS, но в большом количестве компиляторов используется #pragma pack(). Может и тут так?
Degun
Цитата(Сергей Борщ @ Sep 4 2007, 19:03) *
Не знаю CCS, но в большом количестве компиляторов используется #pragma pack(). Может и тут так?

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

typedef __packed struct st_tag {
int a;
short b;
} st_typedef;

на компиляторе cc68k00 мне помогло, там тоже нет
#pragma pack()

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

А что за компилятор такой?
Degun
Цитата(SamHaris @ Sep 6 2007, 09:46) *
Пробуй так:

typedef __packed struct st_tag {
int a;
short b;
} st_typedef;

на компиляторе cc68k00 мне помогло, там тоже нет
#pragma pack()

Не работает.
Цитата(SamHaris @ Sep 6 2007, 09:46) *
А что за компилятор такой?

Точно не знаю.
Vasiliy Rufitskiy
Это, похоже, непоборимо.
Вот что по этому поводу пишет хэлп композера (правда, версии 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);
Degun
Цитата(Vasiliy Rufitskiy @ Oct 25 2007, 19:15) *
Это, похоже, непоборимо.
Вот что по этому поводу пишет хэлп композера (правда, версии 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.
Harbour
packed struct техас не поддерживает в принципе - говорят что этого нет в стандарте, на нужды людей им как обычно наплевать.
novichok_1
я думаю что это так

struct
{

int r;
int t;

} Name; /* имя структуры*/
bukvy
Вот ответ от службы поддержки 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."

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

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

Код
    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 младший и старший разряд, а затем иметь доступ ко всему слову?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.