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

под uint8_t выделяется 2 байта ?

IAR ARM

Подключил к проекту либу. Там есть место

 

PACKED_STRUCT {
        uint8_t    start;
        uint16_t    length_be;
    } prefix;

 

Далее uart-у передается адрес структуры и ее размер.

 

И вот тут начинаются проблемы. Принимающие устройство ожидает три байта, а приходит четыре. К тому-же с не правильным length_be. Так как младший байт этой переменной должен быть вторым а не третьим.

 

Я вижу, что IAR под uint8_t выделяет два байта. sizeof возвращает размер структуры 4.

 

Как заставить IAR выделять правильное количество байт??

 

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

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


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

IAR ARM

Подключил к проекту либу. Там есть место

 

PACKED_STRUCT {
        uint8_t    start;
        uint16_t    length_be;
    } prefix;

 

Далее uart-у передается адрес структуры и ее размер.

 

И вот тут начинаются проблемы. Принимающие устройство ожидает три байта, а приходит четыре. К тому-же с не правильным length_be. Так как младший байт этой переменной должен быть вторым а не третьим.

 

Я вижу, что IAR под uint8_t выделяет два байта. sizeof возвращает размер структуры 4.

 

Как заставить IAR выделять правильное количество байт??

pragma pack (1)

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


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

Я вижу, что IAR под uint8_t выделяет два байта.
Неверно. Под uint8_t выделяется один байт, а вот следом за ним вставляется пустое место для выравнивания следующего поля (uint16_t) на границу 2 байт.

Сработало.
Ага. Здесь сработало, но при этом заодно упаковались и все объявленные следом структуры, а значит доступ к их членам стал байтовым и как следствие медленным, с увеличением размера кода.

 

Надо было разбираться, почему не работет ваш макрос PACKED_STRUCT. Но не видя его определения советовать тут что-то очень трудно.

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


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

просто потом надо написать pragma pack() для воостановления старого выравнивания. (зависит от компилятора)

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


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

просто потом надо написать pragma pack() для воостановления старого выравнивания. (зависит от компилятора)
Вероятно макрос PACKED_STRUCT как-то об этом заботился.

 

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


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

Макрос об этом не заботился, за ним скрывается struct.

 

Скорость и размер не особо важны. В либе проблемы не только во время передачи/приема а вообще в самой библиотеке. Эту библиотеку разработали в digi. Там сплошная работа со структурами и я вижу, что разработчикам часто нравилось работать со структурами как с массивами.

 

Пробовал все сделать правильно и добавил макросы к структурам, но это вылечило только некоторые проблемы. Только глобальная pragma pack (1) убирает все проблемы.

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


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

Макрос об этом не заботился, за ним скрывается struct.

Этот макрос должен писать не автор библиотеки, а тот, кто её портирует на свою архитектуру. Вот кто этот макрос написал, того и спрашивайте, почему он такой. Вполне возможно, что он решил не париться и просто глобально выключить выравнивание структур. Или у него была 8-битная архитектура.

 

Скорость и размер не особо важны.

Тогда просто продолжайте использовать глобальную прагму pack(1). Для удобства её можно вынести в отдельный файл и включать его в каждый компилируемый файл при помощи опции компилятора --preinclude.

Оставьте разборки с выравниванием тому, кому по понадобится оптимизировать эту библиотеку.

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


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

Тогда просто продолжайте использовать глобальную прагму pack(1).
Для такого решения (безотносительно к его качеству) должен иметься специальный инструмент, например в gcc это ключик -fpack-struct[=n].

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


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

В IARE ключевое слово __packed. Действует только на указанную структуру: __packed struct

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


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

Для такого решения (безотносительно к его качеству) должен иметься специальный инструмент, например в gcc это ключик -fpack-struct[=n].

Нету в яре такого ключика. Поэтому я и упомянул --preinclude. Ничего более элегантного не просматривается.

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


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

Нету в яре такого ключика. Поэтому я и упомянул --preinclude. Ничего более элегантного не просматривается.
На нет и суда нет)))

 

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


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

Это была шутка?

 

IAR C/C++ Development Guide

 

__packed

Syntax Follows the generic syntax rules for type attributes that can be used on data, see Type

attributes, page 313.

Description Use the __packed keyword to decrease the data type alignment to 1. __packed can be

used for two purposes:

● When used with a struct or union type definition, the maximum alignment of

members of that struct or union is set to 1, to eliminate any gaps between the

members. The type of each members also receives the __packed type attribute.

● When used with any other type, the resulting type is the same as the type without

the __packed type attribute, but with an alignment of 1. Types that already have an

alignment of 1 are not affected by the __packed type attribute.

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


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

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

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

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

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

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

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

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

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

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