|
|
  |
Выравнивание при доступе к полям структур в Code Composer Studio v. 3.3 |
|
|
|
Sep 4 2007, 12:47
|
Частый гость
 
Группа: Свой
Сообщений: 178
Регистрация: 30-12-04
Из: Москва
Пользователь №: 1 762

|
Имеется следующий код на 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. Как быть в этой ситуации?
|
|
|
|
|
Sep 4 2007, 17:07
|
Частый гость
 
Группа: Новичок
Сообщений: 84
Регистрация: 4-09-07
Из: Москва
Пользователь №: 30 277

|
Цитата(Сергей Борщ @ Sep 4 2007, 19:03)  Не знаю CCS, но в большом количестве компиляторов используется #pragma pack(). Может и тут так? Нет в CCS такая конструкция не работает.
|
|
|
|
|
Sep 6 2007, 05:46
|

Группа: Новичок
Сообщений: 13
Регистрация: 11-08-05
Пользователь №: 7 546

|
Пробуй так: typedef __packed struct st_tag { int a; short b; } st_typedef; на компиляторе cc68k00 мне помогло, там тоже нет #pragma pack() Цитата Имеется следующий код на C++ для 6000-ков А что за компилятор такой?
|
|
|
|
|
Sep 10 2007, 13:02
|
Частый гость
 
Группа: Новичок
Сообщений: 84
Регистрация: 4-09-07
Из: Москва
Пользователь №: 30 277

|
Цитата(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)  А что за компилятор такой? Точно не знаю.
|
|
|
|
|
Oct 25 2007, 15:15
|
Участник

Группа: Новичок
Сообщений: 18
Регистрация: 19-10-07
Пользователь №: 31 519

|
Это, похоже, непоборимо. Вот что по этому поводу пишет хэлп композера (правда, версии 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);
|
|
|
|
|
Oct 26 2007, 05:27
|
Частый гость
 
Группа: Новичок
Сообщений: 84
Регистрация: 4-09-07
Из: Москва
Пользователь №: 30 277

|
Цитата(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.
|
|
|
|
|
Dec 18 2007, 19:08
|
Группа: Новичок
Сообщений: 5
Регистрация: 18-12-07
Из: Azr
Пользователь №: 33 414

|
я думаю что это так
struct {
int r; int t;
} Name; /* имя структуры*/
|
|
|
|
|
Mar 13 2008, 08:36
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 8-09-07
Пользователь №: 30 379

|
Вот ответ от службы поддержки 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."
Так что, они об этой проблеме знают и стараются ее решить. Как скоро - неизвестно. Нам остается только ждать.
|
|
|
|
|
Mar 13 2008, 14:19
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 7-11-06
Пользователь №: 22 046

|
>Как сделать, чтобы выравнивание при доступе к элементам структуры было правильным?
Располагать поля нужно по увеличению размера. Но даже в этом случае адрес следующей структуры будет выровнен на 4 байта.
Сообщение отредактировал Ghost2 - Mar 13 2008, 14:20
|
|
|
|
|
May 12 2008, 10:28
|
Частый гость
 
Группа: Свой
Сообщений: 170
Регистрация: 8-02-06
Из: Москва
Пользователь №: 14 116

|
То есть получается, что считывать данные таким методом: Код 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 младший и старший разряд, а затем иметь доступ ко всему слову?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|