Jump to content

    

Размер unsigned int или int Keil4.5

Добрый день, коллеги.

Месяц использую LPC1768 и только сейчас с "ужасом" заметил, что под переменные unsigned int и int компилятор отводит по 4 байта.

Использую среду Keil 4.5 и постоянно плююсь даже не по причине ее скудости, а по причине неудобности документации на нее и компилятор. Как установить "нормальный" размер этих типов данных размером в 2 байта?

И второй вопрос. Я был уверен, что в Cortex-M3 отсутствует необходимость выравнивания разноразмерных типов данных.

Об этом написано тут

Тем не менее, у себя в реале я этого не вижу. Если за однобайтовой переменной следует четырехбайтовая, то она все равно выравнивается по границе 32 разрядного слова, тоесть остается неиспользуемый промежуток в 3 байта. Что тут не так?

Share this post


Link to post
Share on other sites

Размер int равен размеру машинного слова. В данном случае 32 бита.

Нужно 2 байта - используйте short int (ну или просто short), либо int16_t.

Edited by ohmjke

Share this post


Link to post
Share on other sites
Как установить "нормальный" размер этих типов данных размером в 2 байта?

Никак. 32-х битный int для 32-х битной архитектуры - это и есть норма. Используйте short или типы из <stdint.h>.

 

И второй вопрос. Я был уверен, что в Cortex-M3 отсутствует необходимость выравнивания разноразмерных типов данных.

Об этом написано тут

Тем не менее, у себя в реале я этого не вижу. Если за однобайтовой переменной следует четырехбайтовая, то она все равно выравнивается по границе 32 разрядного слова, тоесть остается неиспользуемый промежуток в 3 байта. Что тут не так?

Необходимость необходимости рознь - эффективность работы с выровненными данными выше, поэтому без нужды паковать их не следует.

Используйте в случае нужды модификатор __packed.

Share this post


Link to post
Share on other sites
Размер int равен размеру машинного слова. В данном случае 32 бита.

Как бы такое утверждение было в основном принято к процессорам семейства х86. Для микроконтроллеров подразумевалось int - 2 байта. Но готов с Вами согласиться, поскольку в Keil нашел предопределенный макрос, который возвращает 4. Но тогда, по логике, long должен иметь удвоенный размер, только не машиннго слова, как Вы написали , поскольку это не команда, а размер шины данных, тоесть 64 бита. Разве не так?

Share this post


Link to post
Share on other sites
Машинное слово — машиннозависимая и платформозависимая величина, измеряемая в битах или байтах (тритах или трайтах), равная разрядности регистров процессора и/или разрядности шины данных.

 

И где это для МК подразумевалось 2 байта? У AVR?

 

Еще из википедии:

Многие языки программирования предлагают выбор между короткими (англ. short), длинными (англ. long) и целыми стандартной длины. Длина стандартного целого типа, как правило, совпадает с размером машинного слова на целевой платформе. Для 16-разрядных операционных систем - этот тип (int) составляет 2 байта и совпадает с типом short int (можно использовать как short, опуская слово int), для 32-разрядных операционных систем он будет равен 4 байтам и совпадает с длинным целым long int (можно использовать как long, опуская слово int), и в этом случае будет составлять 4 байта. Короткое целое short int, для 16-разрядных операционных систем, 32-разрядных операционных систем, 64-разрядных операционных систем составляет — 2 байта. Также в некоторых языках может использоваться тип данных двойное длинное long long, который составляет 8 байт.
Edited by ohmjke

Share this post


Link to post
Share on other sites
Используйте в случае нужды модификатор __packed.

Так можно упаковать только структуры и битовые поля, не так ли?

Переменные базовых типов так не упакуешь.

 

И где это для МК подразумевалось 2 байта?

 

Еще из википедии:

Я согласен с Вами, офицального признания, что int- это 2 байта, нет. Это есть определенное неофицальное соглашение. Впрочем, нет смысла спорить, да я и не за тем спрашиваю. В большенстве систем, даже 32х или даже 64х разрядных есть двухбайтовые типы данных.

Получается, в ARM нет двухбайтового типа данных?

Share this post


Link to post
Share on other sites

Написали же, 2 байтовый это short.

Share this post


Link to post
Share on other sites

Получается, все же есть в <stdint.h> - short

 

 

Получается, все же есть в <stdint.h> - short

Я увидел, благодарствую.

 

Share this post


Link to post
Share on other sites
Переменные базовых типов так не упакуешь.

А вы попробуйте ;)

Share this post


Link to post
Share on other sites
А вы попробуйте ;)

Подскажите метод, как упаковать?

unsigned char A;
unsigned long B;
unsigned char C;

что бы получилось занятыми в памяти не 12 байт, а 6 байт?

Буду весьма благодарен.

Share this post


Link to post
Share on other sites
Подскажите метод, как упаковать? ...что бы получилось занятыми в памяти не 12 байт, а 6 байт?

Вам же выше уже говорили про __packed. Создаете структуру с требуемым набором данных. Сообщаете компилятору, что нужно ее упаковать и готово.

 

Кстати, для определения типов пользуюсь давным-давно уже своим хедером:

/*******************************************************************************
Declared types
*******************************************************************************/

/* Integer */
typedef signed int            INT, *P_INT;
typedef unsigned int        UINT, *P_UINT;
#define MAXUINT                ((UINT)(-1))
#define INTLEN                (sizeof(INT))

/* byte */
typedef signed char            CHAR, *P_CHAR;
typedef unsigned char        UCHAR, *P_UCHAR;

typedef CHAR                INT8, *P_INT8;
typedef UCHAR                UINT8, *P_UINT8;
#define MAXUINT8            ((UINT8)(-1))
#define INT8LEN                (sizeof(INT8))

/* word */
typedef signed short        INT16, *P_INT16;
typedef unsigned short        UINT16, *P_UINT16;
#define MAXUINT16            ((UINT16)(-1))
#define INT16LEN            (sizeof(INT16))

/* double word */
typedef signed long            INT32, *P_INT32;
typedef unsigned long        UINT32, *P_UINT32;
#define MAXUINT32            ((UINT32)(-1))
#define INT32LEN            (sizeof(INT32))

/* quad word */
typedef signed long long    INT64, *P_INT64;
typedef unsigned long long    UINT64, *P_UINT64;
#define MAXUINT64            ((UINT64)(-1))
#define INT64LEN            (sizeof(INT64))

Один файл для всех типов МК, в том числе AVR и ARM

Share this post


Link to post
Share on other sites

Не хотел создавать новую тему... Можно ли спросить здесь:

1. В связи с чем в IAR определены типы uint16_t и подобные, оканчивающиеся на "_t". Всю жись писал полностью "unsigned int" и так далее... Так конечно длиннее и дольше, больше тонера при распечатках, но уже привычно... Зачем эти "_t" определили?

2. Есть ли в IAR возможность подсветить эти типы жирным шрифтом, как стандартные?

Share this post


Link to post
Share on other sites
Не хотел создавать новую тему... Можно ли спросить здесь:

1. В связи с чем в IAR определены типы uint16_t и подобные, оканчивающиеся на "_t". Всю жись писал полностью "unsigned int" и так далее... Так конечно длиннее и дольше, больше тонера при распечатках, но уже привычно... Зачем эти "_t" определили?

2. Есть ли в IAR возможность подсветить эти типы жирным шрифтом, как стандартные?

Это не только в IAR.

Думаю, просто для удобства - короче и сразу видно размер.

И лично для меня так действительно удобнее.

Edited by ohmjke

Share this post


Link to post
Share on other sites
Зачем эти "_t" определили?
Это типа сообщение человечеству, что это "тип данных". Я например (по рекомендации мелкософта;)) Глобальные переменные называю с первыми символами "g_" (global). Например "g_SysTime". Так же и здесь - uint16_t (uint16 type)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this