реклама на сайте
подробности

 
 
6 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Приведение типа указателя на элемент структуры
ViKo
сообщение Oct 17 2012, 10:51
Сообщение #1


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Допустим, имеется структура из байтов. Хочу инициализировать сразу 2 байта 16-битовым числом, или сразу 4 байта 32-битовым числом. Привожу указатель к нужному типу.
Код
typedef struct {
  __IO uint8_t A;
  __IO uint8_t B;
  uint16_t RES;
} DEV_t;

  DEV_t Dev;
  DEV_t *pDev = &Dev;

  pDev->A = 0x55;
  pDev->B = 0xAA;
  (uint16_t)pDev->A = 0x3333;
  (uint32_t)pDev->A = 0x01234567;


Код работает. Но Keil выдает предупреждения:
source\Exercises.c(117): warning: #1441-D: nonstandard cast on lvalue
Есть ли способ написать так, чтобы Keil не возмущался?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 17 2012, 11:11
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



*(uint16_t*)&Dev.A = 0x55AA;


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 11:20
Сообщение #3


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(AHTOXA @ Oct 17 2012, 14:11) *
*(uint16_t*)&Dev.A = 0x55AA;

Да, так работает без предупреждений.
И без специально созданного указателя. sm.gif
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 17 2012, 11:27
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Но это хак, работоспособность которого зависит от выравнивания элементов структуры. Надо по крайней мере комментарий про это написать рядышкомsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 11:36
Сообщение #5


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(AHTOXA @ Oct 17 2012, 14:27) *
Но это хак, работоспособность которого зависит от выравнивания элементов структуры. Надо по крайней мере комментарий про это написать рядышком

Для того и вводятся резервные места, ну, как в stm32xxx.h
Код
typedef struct
{
  __IO uint32_t DR;         /*!< CRC Data register,             Address offset: 0x00 */
  __IO uint8_t  IDR;        /*!< CRC Independent data register, Address offset: 0x04 */
  uint8_t       RESERVED0;  /*!< Reserved, 0x05                                      */
  uint16_t      RESERVED1;  /*!< Reserved, 0x06                                      */
  __IO uint32_t CR;         /*!< CRC Control register,          Address offset: 0x08 */
} CRC_TypeDef;

По такой аналогии и создавал. Правильное заполнение структуры будет обеспечено, а обращение возможно по любому (невыровненному) адресу. Cortex-M3 же.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Oct 17 2012, 11:58
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(ViKo @ Oct 17 2012, 14:36) *
Правильное заполнение структуры будет обеспечено, а обращение возможно по любому (невыровненному) адресу. Cortex-M3 же.

А на каких архитектурах при таком обращении возникнут проблемы (и какие)?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 12:06
Сообщение #7


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Артём_ @ Oct 17 2012, 14:58) *
А на каких архитектурах при таком обращении возникнут проблемы (и какие)?

*(uint32_t *) &Dev.B = 0x02468ACE;
для ARM7. обращение по невыровненому адресу.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 17 2012, 12:12
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(ViKo @ Oct 17 2012, 16:06) *
*(uint32_t *) &Dev.B = 0x02468ACE;
для ARM7. обращение по невыровненому адресу.

то есть перед объявлением добавляем __packed?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Oct 17 2012, 12:18
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(ViKo @ Oct 17 2012, 15:06) *
*(uint32_t *) &Dev.B = 0x02468ACE;
для ARM7. обращение по невыровненому адресу.

И что будет ? HardFault?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 12:19
Сообщение #10


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(toweroff @ Oct 17 2012, 15:12) *
то есть перед объявлением добавляем __packed?

У меня Cortex-M3, ничего не добавляю, и так хорошо. laughing.gif
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Oct 17 2012, 12:19
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(toweroff @ Oct 17 2012, 15:12) *
то есть перед объявлением добавляем __packed?

Без packed компилятор сам выравняет?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 12:20
Сообщение #12


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Артём_ @ Oct 17 2012, 15:18) *
И что будет ? HardFault?

А то! sm.gif
http://www.google.by/webhp?rlz=1C1GGGE_ruB...745&bih=925

Добавлю. Мне не нужно "утрамбовать" структуру. Наоборот, я описываю в структуре регистры внешнего устройства, в частности, контроллера ЖКИ. С расположением регистров по конкретным адресам. Все, как в упомянутой stm32xxx.h. А обращаться хочу не только по байтам, но и целыми словами.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 17 2012, 12:43
Сообщение #13


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(_Артём_ @ Oct 17 2012, 15:58) *
А на каких архитектурах при таком обращении возникнут проблемы (и какие)?

На многих, отличных от 8 бит.
Например, MSP430. По умолчанию выравнивание по границе слова.
Выровненный char займет 2 байта, старший байт 16р инициализатора вместо второго чара улетит в пустоту

Цитата(ViKo @ Oct 17 2012, 16:20) *
я описываю в структуре регистры внешнего устройства, в частности, контроллера ЖКИ.

Вот в таком случае аттрибут упаковки строго обязателен.
Иначе такие чудеса могут начаться..
Пишешь байт в один регистр, а он улетает в соседний или через несколько

Конечно, не ваш конкретный случай, но все же


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 12:46
Сообщение #14


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(MrYuran @ Oct 17 2012, 15:43) *
Вот в таком случае аттрибут упаковки строго обязателен.
Иначе такие чудеса могут начаться..
Пишешь байт в один регистр, а он улетает в соседний или через несколько

Так заполняю же все адреса подряд! RESERVED вставляю во все дыры! sm.gif
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 17 2012, 12:54
Сообщение #15


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ViKo @ Oct 17 2012, 16:46) *
Так заполняю же все адреса подряд! RESERVED вставляю во все дыры! sm.gif

А неважно.
Выровняет по границе машинного слова (16/32/64) - и все ваши RESERVED превратятся в дополнительные 16/32/64р "дыры"
Очень аккуратно нужно действовать, иначе наколоться можно очень неприятно.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 13:10
Сообщение #16


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(MrYuran @ Oct 17 2012, 15:54) *
А неважно.
Выровняет по границе машинного слова (16/32/64) - и все ваши RESERVED превратятся в дополнительные 16/32/64р "дыры"

Не выравняет. sm.gif Потому что имеется следующий код.
Код
typedef struct {
  __I uint8_t RCR;    //<! Revision Code Register,            0x00
  __I uint8_t DBSR;    //<! Dislpay Buffer Size Register,        0x01
  __I uint8_t CRR;    //<! Configuration Readback Register,        0x02
} ReadOnlyConf_t;    //<! Read-Only Configuration Registers

typedef struct {
  __IO uint8_t MCCR;    //<! Memory Clock Configuration Register,    0x04
  __IO uint8_t PCCR;    //<! Pixel Clock Configuration Register,    0x05
} ClockConf_t;        //<! Clock Configuration Registers
...

#define DPYCTRL_BASE    ((uint32_t)0x6C000000)    //<! Dysplay base address
#define S1DREGS_BASE    DPYCTRL_BASE        //<! S1D13706 registers base

#define READONLYCONF_BASE    S1DREGS_BASE
#define CLOCKCONF_BASE        S1DREGS_BASE + 0x04
#define LOOKUPTABLE_BASE    S1DREGS_BASE + 0x08
...
#define READONLYCONF    ((ReadOnlyConf_t *) READONLYCONF_BASE)
#define CLOCKCONF    ((ClockConf_t *) CLOCKCONF_BASE)
#define LOOKUPTABLE    ((LookUpTable_t *) LOKUPTABLE_BASE)
...

А дальше - обращения по указателям...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 17 2012, 15:18
Сообщение #17


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Oct 17 2012, 14:36) *
Для того и вводятся резервные места, ну, как в stm32xxx.h

Не надо брать пример с индуистского кода. Правильный ответ(причем, всегда)
Код
typedef struct
{
  __IO uint32_t DR;         /*!< CRC Data register,             Address offset: 0x00 */
  union
{
  __IO uint8_t  reg8bit;        /*!< CRC Independent data register, Address offset: 0x04 */
  uint32_t IDR_space;
} IDR;
  __IO uint32_t CR;         /*!< CRC Control register,          Address offset: 0x08 */
} CRC_TypeDef;


Почему у них идеологически не так? Патамушо эти хедеры не для того, чтобы ими пользоваться! sm.gif
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Oct 17 2012, 15:44
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(_Pasha @ Oct 17 2012, 18:18) *
Патамушо эти хедеры не для того, чтобы ими пользоваться! sm.gif

Интересно, а чем же пользоваться?
Самому хидеры на процы делать?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 17 2012, 16:21
Сообщение #19


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(_Артём_ @ Oct 17 2012, 18:44) *
Интересно, а чем же пользоваться?
Самому хидеры на процы делать?

Я тут давеча психанул и наваял по означенному выше принципу. Ессно, только структуры, без всяких функций сомнительного сервиса. Но у проекта, который сейчас пилю, уже поезд ушел, тестинг откладывается.
Странно, но LPC такой ненависти не вызывают. Очень странно... sm.gif
Вообще, я там сильно повыделывался - дал битовым полям осмысленные имена... там по-хорошему надо двуязычие, тоже на основе union{}- с сохранением мнемоники и с сохранением смысла... этот момент разрулю - будет тыщи три строк.
И вроде бы взять да и сделать базу в libreoffice base, чтоб генерило то,что надо... блин, лень забадала.

Сообщение отредактировал _Pasha - Oct 17 2012, 16:27
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 17 2012, 16:48
Сообщение #20


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



А в каком случае может не сработать индуистский вариант? Я что-то с наскока не смог добиться, чтобы размер структуры
Код
typedef struct
{
  uint32_t DR;
  uint8_t  IDR;
  uint8_t  spacer;
  uint16_t  spacer2;
  uint32_t CR;
} CRCpeDef;

был не 12. Пробовал все мыслимые варианты -fpack-struct=1, 2, 4, 8, 16.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 17 2012, 17:07
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Ух как у меня все это перекликается... и с volatile, и со структурами
Тоже бодаюсь. Чуть позже выложу, если позволите, в этой теме, ибо оооочень похоже
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 17:31
Сообщение #22


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Pasha @ Oct 17 2012, 18:18) *
Не надо брать пример с индуистского кода. Правильный ответ(причем, всегда)
...

Я тоже кинулся было править stm32f2xx.h, когда увидел, что не могу одной командой установить и сбросить биты в порту. Из-за
Код
...
  __IO uint16_t BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
  __IO uint16_t BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  // __IO uint32_t BSRR;        // GPIO port bit set/reset: 0xRRRRSSSS, Address offset: 0x18
...
} GPIO_TypeDef;

Причем, BSRRL отвечает за установку бита, а BSRRH - за сброс.
Но при пользовании объединениями в имени регистра появляется дополнительное обозначение, которого не хочу.
Поэтому приведение типа указателя для меня более приемлемо.

А насчет библиотеки - функциями не пользуюсь.
А насчет определения битов - #define меня устраивают.
Главное, чтобы код не разбухал.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 17 2012, 17:47
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Итак, добавляю sm.gif
есть две области в ARM968E-S
в первой висит 16-битный супресс USB, во второй - NOR Flash

Читается/пишется в первую область только по/из фиксированным адресам
Во вторую - и так, и с инкрементом

оптимизация компилятора в Time и O3

Шины. 1-я с супрессом - 16бит, 2-я - 32 бит

Что-то фигню наблюдаю

Первая область объявлена как
Код
#define        FX2_FIFO2            (*(volatile unsigned int *)(FX2_BASE_ADDR + (0x00UL<<2)))
#define        FX2_FIFO4            (*(volatile unsigned int *)(FX2_BASE_ADDR + (0x02UL<<2)))


вторая - также через volatile, но в своем диапазоне

Доступ к памяти осцилл показывает и, судя по тестам, точно как и надо

А вот данные - не пойми чего
Для пересылки и сокращения доступа к той и другой области памяти попробовал сделать union с тремя полями - U16, U16 и U32
Например, чтение из первой области - в две U16 подряд, потом из U32 - в другую область запись

Шаманство sm.gif Не работает
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 17 2012, 18:22
Сообщение #24


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Oct 17 2012, 20:31) *
Я тоже кинулся было править stm32f2xx.h, когда увидел, что не могу одной командой установить и сбросить биты в порту. Из-за[кусь]
Поэтому приведение типа указателя для меня более приемлемо.


Не пойму, кто заремил BSRR, милое дело ©
Код
Inline void pin_set_by_msk(const GPIO_typedef *port, const uint16_t msk, const bool state)
{
  port->BSRR = state?(msk):(msk<<16);
}

компиляется в минимум,- жаль, редко, когда в две-это при интенсивных операциях -инструкции

Сообщение отредактировал _Pasha - Oct 17 2012, 18:24
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 18:33
Сообщение #25


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Pasha @ Oct 17 2012, 21:22) *
Не пойму, кто заремил BSRR, милое дело ©

Я же и закомментировал. Сам приписал, сам убрал. Когда возникла дилемма - или писать всегда по 32 бита, или писать, когда надо, по 16-битов. В-общем, надо было иметь и ту, и другую возможность. А union ... уже говорил ... А *(uint32_t *) &GPIOB.BSRRL - то шо надо!
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 17 2012, 18:35
Сообщение #26


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(_Pasha @ Oct 18 2012, 00:22) *
Не пойму, кто заремил BSRR, милое дело ©

Дык, индусы, кто ж ещёsm.gif Причём битовые маски оставили как для 32-битного BSRR. (Это для F2xx.)
Я всё же такого не стерпел, и переписал это определение.
_Pasha, так в каком случае индуистский подход с ручными отступами в структурах может привести к неправильному результату? Или здесь речь чисто об эстетике? sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 17 2012, 18:41
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Админы, я так понимаю, здесь свой колхоз sm.gif
я это все отправлю а "ARM, 32bit", здесь уберите, мешает всем
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 18:47
Сообщение #28


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Pasha @ Oct 17 2012, 21:22) *
port->BSRR = state?(msk):(msk<<16);
...
компиляется в минимум,- жаль, редко, когда в две-это при интенсивных операциях -инструкции

Это если один бит задавать. А по началу можно весь порт установить в нужное состояние.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 17 2012, 18:50
Сообщение #29


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(AHTOXA @ Oct 17 2012, 21:35) *
_Pasha, так в каком случае индуистский подход с ручными отступами в структурах может привести к неправильному результату? Или здесь речь чисто об эстетике? sm.gif

Вообще-то подозрения в выравнивании - не мои. Если MrYuran сталкивался, думаю, он поделится.
Хотя, странно -fpack-struct=8 должен бы, как представляется...
Я только выразил недоумение по поводу головоломок там, где их быть не должно, при передвижении на круглых колесах, тсз.sm.gif

Сообщение отредактировал _Pasha - Oct 17 2012, 18:52
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 17 2012, 18:52
Сообщение #30


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ViKo @ Oct 18 2012, 00:47) *
Это если один бит задавать. А по началу можно весь порт установить в нужное состояние.

Вообще-то для этого есть ODR sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 17 2012, 18:56
Сообщение #31


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Oct 17 2012, 21:47) *
Это если один бит задавать. А по началу можно весь порт установить в нужное состояние.

wacko.gif Да хоть 100! Из 16-ти

Сообщение отредактировал _Pasha - Oct 17 2012, 18:57
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 18:56
Сообщение #32


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(AHTOXA @ Oct 17 2012, 21:52) *
Вообще-то для этого есть ODR sm.gif

Точно! Что-то я упустил его из виду! Вот спасибо! sm.gif Пойду поправлю нафиг. Еще один шаг к совершенству.
А он у них (индусов) - тоже, 32-х разрядный! sm.gif
Кстати, если про BSRR в Ref Manual написано "These bits are write-only and can be accessed in word, half-word or byte mode", то про доступ к ODR - молчок. Можно ли туда послать 16 битовое число?

Про IDR написано конкретно: These bits are read-only and can be accessed in word mode only.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 17 2012, 18:59
Сообщение #33


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(_Pasha @ Oct 18 2012, 00:50) *
Вообще-то подозрения в выравнивании - не мои. Если MrYuran сталкивался, думаю, он поделится.

А в чём тогда "правильность" кода с union-ами?
Цитата(_Pasha @ Oct 18 2012, 00:50) *
Хотя, странно -fpack-struct=8 должен бы, как представляется...

Как я понял, -fpack-struct[=x] может только сильнее упаковать структуру. Проредить её может __attribute__ ((aligned (x))). Но его нужно явно указывать для члена структуры, случайно так не сделать.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 17 2012, 19:17
Сообщение #34


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(AHTOXA @ Oct 17 2012, 21:59) *
А в чём тогда "правильность" кода с union-ами?

В данном случае - чисто йуридически
Цитата
warning: #1441-D: nonstandard cast on lvalue

Где оно выползет боком - фантазии не хватает представить.
Для АРМов сумасшедшие компиляторы а-ля CodeVision для АВРок - существуют? sm.gif
Если бы были - там бы и повылезло.

Сообщение отредактировал _Pasha - Oct 17 2012, 19:20
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 17 2012, 19:20
Сообщение #35


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Pasha @ Oct 17 2012, 22:17) *
В данном случае - чисто йуридически
Где оно выползет боком - фантазии не хватает представить.

Нигде. Только сон будет менее спокойным.
P.S. Видно по результатам компиляции - все нормально.
Go to the top of the page
 
+Quote Post
Дмитриос
сообщение Oct 17 2012, 20:22
Сообщение #36


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 22-04-10
Пользователь №: 56 826



Цитата(_Pasha @ Oct 17 2012, 20:21) *
Я тут давеча психанул и наваял по означенному выше принципу. Ессно, только структуры, без всяких функций сомнительного сервиса. Но у проекта, который сейчас пилю, уже поезд ушел, тестинг откладывается.

Простите а вот под какой контроллер вы так сделали?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 17 2012, 20:39
Сообщение #37


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Дмитриос @ Oct 17 2012, 23:22) *
Простите а вот под какой контроллер вы так сделали?

STM32f100
Но, сделал - и пожалел. Надо сразу базу данных заводить и оттуда генерить. Писанина - плохой стиль.
Go to the top of the page
 
+Quote Post
Дмитриос
сообщение Oct 17 2012, 20:53
Сообщение #38


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 22-04-10
Пользователь №: 56 826



Цитата(_Pasha @ Oct 18 2012, 00:39) *
STM32f100
Но, сделал - и пожалел. Надо сразу базу данных заводить и оттуда генерить. Писанина - плохой стиль.

А разве производитель CMSIS ные либы со структурами не создаёт для регистров данного контроллера или у Вас свои какие-то структуры?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 17 2012, 21:31
Сообщение #39


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Дмитриос @ Oct 17 2012, 23:53) *
А разве производитель CMSIS ные либы со структурами не создаёт для регистров данного контроллера или у Вас свои какие-то структуры?

Они обходят стороной битовые поля, имея ввиду, что применение их в общеупотребительном смысле неэффективно. Я так думаю, зря.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 18 2012, 03:39
Сообщение #40


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(_Pasha @ Oct 18 2012, 01:17) *
В данном случае - чисто йуридически

Да нет же, я не об этом! sm.gif Там ViKo просто не то не к тому привёл.
Я вот о чём. Чем ваш вариант
Код
typedef struct
{
  __IO uint32_t DR;
  union
{
  __IO uint8_t  reg8bit;
  uint32_t IDR_space;
} IDR;
  __IO uint32_t CR;
} CRC_TypeDef;

лучше индуистского варианта
Код
typedef struct
{
  __IO uint32_t DR;
  __IO uint8_t  reg8bit;
  __IO uint8_t  spacer;
  __IO uint16_t  spacer2;
  __IO uint32_t CR;
} CRC_TypeDef;

?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 18 2012, 05:12
Сообщение #41


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(_Pasha @ Oct 17 2012, 22:50) *
Вообще-то подозрения в выравнивании - не мои. Если MrYuran сталкивался, думаю, он поделится.

Сталкивался, не то слово.
MSPGCC образца 2008 года и iostructures.h
Причем, там явно было указано __attribute__ (("packed")) под каждой структурой, однако ж..
После серии необъяснимых чудес пришлось лезть в листинг и сверять адреса регистров.
Помогло только -fpack-struct, когда все структуры принудительно упаковывались.
После того все переписал на макросы Волкова.
Конечно, не так красиво, зато работает железно.

Хотя, сейчас поглядел...
Код
#if defined(__MSP430_HAS_PORT0__)
struct port0_t {
  ioregister_t    in;    /* Input */
  ioregister_t    out;    /* Output */
  ioregister_t    dir;    /* Direction */
  ioregister_t    ifg;    /* Interrupt Flag */
  ioregister_t    ies;    /* Interrupt Edge Select */
  ioregister_t    ie;    /* Interrupt Enable */
};

__MSP430_EXTERN__ struct port0_t port0 asm("0x0010");
#endif


Здесь почему-то упаковки нет.. Странно..
Это в корне меняет дело, а я на компилятор грешил.
Но суть то этого не меняется. Автоматически выровненная структура "прореживается" и все адреса сползают.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 18 2012, 06:14
Сообщение #42


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MrYuran @ Oct 18 2012, 11:12) *
Это в корне меняет дело
...
Но суть то этого не меняется.

Жжоте biggrin.gif
Тем не менее. test.c:
Код
typedef struct
{
    unsigned char a;
    unsigned char b;
}str;

char zzz[1 - 2*(sizeof(str) != 2)];


gcc -c test.c - порядок.
avr-gcc -c test.c - порядок.
arm-kgp-gcc -c test.c - порядок.
arm-none-eabi-gcc -c test.c - порядок.
msp430-gcc -c test.c - порядок.

Что надо сделать, чтобы "проредило"?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 18 2012, 06:25
Сообщение #43


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(AHTOXA @ Oct 18 2012, 10:14) *
Что надо сделать, чтобы "проредило"?

Я не знаю, что надо сделать, но точно знаю теперь, чего не надо..
Не надо использовать такие структуры без принудительной упаковки, во избежание.
Мне совершенно было не смешно, когда port1.out.pin3 = 1 махал битами в регистре dir вместо out (а это ещё надо было найти)


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 18 2012, 06:55
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(AHTOXA @ Oct 18 2012, 10:14) *
Что надо сделать, чтобы "проредило"?

Вставить #pragma pack(n) или указать транслятору -fpack-struct=n cо значением n отличным от 1.
К сожалению, в документации на gcc нигде нет упоминания: какое значение n (величина выравнивания) принято "по-умолчанию"...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 18 2012, 07:44
Сообщение #45


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(AHTOXA @ Oct 18 2012, 06:39) *
Да нет же, я не об этом! sm.gif Там ViKo просто не то не к тому привёл.

Дык я это "не то не к тому" унаследовал, пытаясь сказать, что сабжевое приведение - лишняя суета и потенциальный источник проблем. Ну не может быть, чтобы хаки и нормальные построения вели себя везде одинаково!
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 18 2012, 07:49
Сообщение #46


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MrYuran @ Oct 18 2012, 12:25) *
Я не знаю, что надо сделать, но точно знаю теперь, чего не надо..
Не надо использовать такие структуры без принудительной упаковки, во избежание.
Мне совершенно было не смешно, когда port1.out.pin3 = 1 махал битами в регистре dir вместо out (а это ещё надо было найти)
Скорее всего был локальный глюк какой-то конкретной версии mspgcc. Хотя принудительная упаковка - дело несложное, можно и её добавить, для пущей уверенности.

Цитата(Палыч @ Oct 18 2012, 12:55) *
Вставить #pragma pack(n) или указать транслятору -fpack-struct=n cо значением n отличным от 1.
К сожалению, в документации на gcc нигде нет упоминания: какое значение n (величина выравнивания) принято "по-умолчанию"...

Нет, ничего из этого не увеличивает размер структуры. Проверил и с #pragma pack(x), и с -fpack-struct=x (x={4,8,16,32}), и с ними обоими одновременно.
До кучи проверил __attribute__ ((packed)) и __attribute__ ((aligned (x))) для типа.
Размер структуры равен 2, как я не извращался sm.gif
Единственный вариант, который изменил размер, был вот такой:
Код
typedef struct
{
    unsigned char a __attribute__ ((aligned (8)));
    unsigned char b __attribute__ ((aligned (8)));
}str;

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

Цитата(_Pasha @ Oct 18 2012, 13:44) *
Дык я это "не то не к тому" унаследовал, пытаясь сказать, что сабжевое приведение - лишняя суета и потенциальный источник проблем.

А, вон оно что! Теперь понялsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 18 2012, 07:54
Сообщение #47


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Pasha @ Oct 18 2012, 10:44) *
Ну не может быть, чтобы хаки и нормальные построения вели себя везде одинаково!

Приведение типов - не хак. А осознанная необходимость. Я не с дырами борюсь, их у меня нет. А хочу писать не только 8-битовыми словами, но и 16-битовыми, 32-битовыми. Cortex-M это позволяет делать, начиная с любого адреса. Тем более, регистры микроконтроллера (или контроллера ЖКИ, который использую) и так выровнены по адресам.
Приведение типов указателя - обычное дело.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 18 2012, 08:16
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(AHTOXA @ Oct 18 2012, 11:49) *
Нет, ничего из этого не увеличивает размер структуры.
А теперь попробуйте проверить на такой структуре:
Код
typedef struct
{
    unsigned char a;
    unsigned int  b;
    unsigned char c;
}str;
Go to the top of the page
 
+Quote Post
XVR
сообщение Oct 18 2012, 08:23
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Вообще то компиляторы упаковывают структуры не от их [компилятора] большого желания, а от требования выполнить ограничения по выравниванию для полей этих самых структур. Так что, если у вас в структуре нет полей с требованиями по выравниванию (например у вас там все char) - то ничего выравниваться и не будет. А вот если есть - то перед этим полем может появится дыра, и вся структура в целом получит ограничение по выравниванию, как для этого поля (что в свою очередь может добавить дыру и в конце структуры)
Например (предполагаю требования по выравниванию на размер поля):
Код
struct {
int8_t f8;
int16_t f16;
int32_t f32;
int8_t  f8_2;
};
// Превратится в
struct {
int8_t f8;
int   :8; // Выравнивание для f16 на границу 2х байтов
int16_t f16;
int  :16; // Выравнивание для f32 на границу 4х байтов
int32_t f32;
int8_t f8_2;
int :24; // Выравнивание размера всей структуры, как требует поле f32
};
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 18 2012, 08:27
Сообщение #50


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(XVR @ Oct 18 2012, 11:23) *
int :16; // Выравнивание для f32 на границу 4х байтов

лишнее
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 18 2012, 08:43
Сообщение #51


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Oct 18 2012, 10:54) *
Приведение типов - не хак. А осознанная необходимость.
***
Cortex-M это позволяет делать, начиная с любого адреса.

biggrin.gif А сколько воплей у народа по поводу невыровненного доступа на AT91** например! Там не особо позволяет 7tdmi.

Цитата(ViKo @ Oct 18 2012, 11:27) *
лишнее

Оно уже для другого: читаем программу и если чего-то надо добавить, сразу видим, сколько бит осталось.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 18 2012, 08:45
Сообщение #52


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Палыч @ Oct 18 2012, 14:16) *
А теперь попробуйте проверить на такой структуре:

Да, но речь шла о структурах, уже имеющих вручную сформированные отступы, типа такой:
Код
typedef struct
{
    uint8_t a;
    uint8_t padder1;    // - отступ
    uint16_t b;
    uint16_t padder2;  // - отступ
    uint32_t c;
}str;

Такие структуры используются, в частности, в заголовочных файлах от ST для описания периферии процессоров STM32. И меня интересует вопрос, могут ли такие структуры при каких-либо условиях перестать соответствовать описываемой ими периферии.
Пока получается, что всё нормально, соответствуют при любых ключах компиляции. (Ну, кроме непонятного случая, описанного MrYuran-ом)


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
XVR
сообщение Oct 18 2012, 08:47
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(ViKo @ Oct 18 2012, 12:27) *
лишнее
Да, точно. Просчитался laughing.gif
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 18 2012, 12:23
Сообщение #54


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(Палыч @ Oct 18 2012, 10:55) *
Вставить #pragma pack(n) или указать транслятору -fpack-struct=n cо значением n отличным от 1.


Раз тут пошли "страшные истории"...
pragma pack(n) надо обязательно закрывать pragma pack()
При включении заголовка с незакрытой прагмой такие интересные косяки проявляются - все структуры в одном модуле сами собой "упаковываются", а в другом - остаются неупакованными, в зависимости от последовательности #include.

Пример для наглядности:
Код
a.h:
#pragma pack (1)

b.h
typedef struct .... b_struct;

a.c
#include "a.h"
#include "b.h"
b_struct A;

b.h
#include "b.h"
b_struct B;


Так вот, A и B получились РАЗНЫЕ, хотя этого вряд-ли кто-то добивался :-)
Короче, плохая это прагма, не ленитесь писать атрибуты для каждой структуры.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 18 2012, 14:47
Сообщение #55


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(AHTOXA @ Oct 18 2012, 11:45) *
Пока получается, что всё нормально, соответствуют при любых ключах компиляции. (Ну, кроме непонятного случая, описанного MrYuran-ом)
Там, я так понял, ещё битовые поля были в подструктурах ioregister_t.
Что-то могло и на этом набежать.
Скажем,
Код
typedef {
    unsigned f : 1;
} flag_t;

typedef {
    flag_t a;
    flag_t b;
} flags2_t;
структура flags2_t займёт 2*sizeof(unsigned), а не один байт. Причём никакие pack не помогут.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
_pv
сообщение Oct 18 2012, 15:51
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(esaulenka @ Oct 18 2012, 19:23) *
Короче, плохая это прагма, не ленитесь писать атрибуты для каждой структуры

а если есть некая структура
Код
typedef struct{
  u8 b;
  u32 c;  
  u8 d;
  u16 a;  
} t_struct_A;


и указатель
Код
t_struct_A * p;

который еще потом может вдруг оказаться совсем невыровненным, ну там преамбула например частично потерялась:
Код
u8 buff[100500];
p = &buff[17];

в каком именно месте и какие прагмы должны стоять чтобы p->c = 0xABCD1234; нормально работало всегда и везде?
или так лучше вообще не делать, а данные просто макросами по байтам по смещениям вытаскивать чтобы ни от платформы ни от компилятора не зависеть?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 18 2012, 16:20
Сообщение #57


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ReAl @ Oct 18 2012, 20:47) *
Там, я так понял, ещё битовые поля были в подструктурах ioregister_t.
Что-то могло и на этом набежать.

Наверное.
Ну а в результате, какой будет вывод? Можно безбоязненно пользоваться структурами от ST? Или ждать, когда _Pasha сделает базу данных? sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 19 2012, 04:41
Сообщение #58


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(AHTOXA @ Oct 18 2012, 19:20) *
Можно безбоязненно пользоваться структурами от ST?

Если программируем аппаратные средства микроконтроллеров STM32xxx, то используются не структуры, а указатели на типы структур, расположенные по фиксированным адресам.
Если просто пользуемся структурами, подобными предложенным ST, то не все ли равно, как упакованы данные? Куда записали, оттуда и прочитаем.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 19 2012, 04:59
Сообщение #59


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ViKo @ Oct 19 2012, 10:41) *
Если программируем аппаратные средства микроконтроллеров STM32xxx, то используются не структуры, а указатели на типы структур, расположенные по фиксированным адресам.

Какая нафиг разница? Если структура вдруг разъедется, то мы промахнёмся мимо нужного регистра и по указателюsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 19 2012, 05:49
Сообщение #60


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(AHTOXA @ Oct 19 2012, 07:59) *
Какая нафиг разница? Если структура вдруг разъедется, то мы промахнёмся мимо нужного регистра и по указателюsm.gif

Как же она разъедется, если указателю передан конкретный адрес! А дыры зарезервированы неиспользуемыми переменными.
P.S. Мы же ее (структуру) уже разъехали разъездили раскатали растянули.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 19 2012, 07:31
Сообщение #61


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ViKo @ Oct 19 2012, 11:49) *
Мы же ее (структуру) уже разъехали разъездили раскатали растянули.

Так вот я и выясняю, не может ли она после этого разъехаться ещё большеsm.gif
Представьте, что есть ключ компилятора, который каждый байт в структуре выравнивает на границу слова. С таким ключом всё наше растягивание пойдёт насмарку.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 19 2012, 09:27
Сообщение #62


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(AHTOXA @ Oct 19 2012, 10:31) *
Так вот я и выясняю, не может ли она после этого разъехаться ещё большеsm.gif
Представьте, что есть ключ компилятора, который каждый байт в структуре выравнивает на границу слова. С таким ключом всё наше растягивание пойдёт насмарку.

Самое простое - не морочить, а заложить где-то assert, только вот что лучше проверять: небось, sizeof какой-то тестовой структуры, не обязательно прям-таки осмысленной и привязанной к реальным портам, но с использованием всех индуистских _IO32 и прочая.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 19 2012, 09:32
Сообщение #63


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



К счастью, в железе STM32 адреса устройств уже распределены так, что "упаковываются" в структурах согласно своему естественному размеру, int16_t по границам полуслова, int32_t по границам слова. Во всяком случае, я не заметил, чтобы где-то в stm32fxx.h было не так. Поэтому, если не насиловать компилятор прагмами pack(n), ничто расползаться не должно.
А __packed может только утоптать структуру, но не раздвинуть ее. А от этого мы уже защитились RESERVED.
Так, вроде?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 19 2012, 09:57
Сообщение #64


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Oct 19 2012, 12:32) *
К счастью, в железе STM32 [...]

В принципе, тут зацепились мы за платформенно-независимый вопрос.
Цитата
Поэтому, если не насиловать компилятор прагмами pack(n)

... а также приведением типов указателей на элемент структуры sm.gif ...
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 26 2012, 20:10
Сообщение #65


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(ViKo @ Oct 17 2012, 09:51) *
Допустим, имеется структура из байтов. Хочу инициализировать сразу 2 байта 16-битовым числом, или сразу 4 байта 32-битовым числом. Привожу указатель к нужному типу

Похоже, при формировании структуры си-компилятор находит элемент с максимальной длиной и выделяет каждому элементу структуры размер памяти, равный максимальной длине. По крайней мере, для кейловского компилятора я это доказал. Выделил структуру
typedef struct
{
unsigned long VARA;
unsigned char VARB;
unsigned int VARC;
}
CRCSTRUCT;

CRCSTRUCT STRD;

и в дибаггере стал туда писать побайтно, начиная с VARА. В VARА записалось 4 байта, как и ожидалось, в VARВ записался один байт, остальные три писались в никуда и не отображались, в VARC записалось два байта, остальные записались в никуда.

Так что дырки в структурах всегда будут, если структура содержит элементы разной длины.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Nov 9 2012, 18:48
Сообщение #66


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



yeah.gif
Есть Грабля!
CODE
typedef struct
{
char id[2];
uint32_t size;
char reserved[4];
uint32_t offset;
uint32_t bmp_infolen;
uint32_t width;
uint32_t height;
uint16_t planes;//number of
uint16_t bits_per_pix;
uint32_t compress_type;
uint32_t picture_size;
uint32_t Hresolution;
uint32_t Vresolution;
uint32_t used_colors;
uint32_t important_colors;
} bmp_header_t;

Компилим
Код
gcc версия 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

с дефолтными настройками code::blocks (уверяю, там ничего страшного нету, выравнивание нигде принудительно не включено)
Пишет после bmp_header.id два нулевых байта, также при выводе его размера показывает 56 байт супротив 54-х.
В общем, подарок для АНТОХИ. sm.gif
ЗЫ причем, сгенеренный и исходный BMP отличаются ровно на этих 2 байта
PPS добавили #pragma pack(1) - получили всё, что надо. 54 байта.
Оттакот!
ppps Что-то пользоваться таким ГЦЦ расхотелось...

Сообщение отредактировал _Pasha - Nov 9 2012, 19:11
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 9 2012, 19:29
Сообщение #67


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (_Pasha @ Nov 9 2012, 20:48) *
CODE
typedef struct
{
    char        id[2];
    uint32_t    size;
И что же вы ожидали (надеюсь, это был не AVR или MSP430)?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 9 2012, 19:33
Сообщение #68


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(_Pasha @ Nov 10 2012, 00:48) *
yeah.gif
Есть Грабля!

Да вроде не особо, uint32_t выровняли на 4 байта. Не вижу криминалаsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Nov 9 2012, 19:43
Сообщение #69


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(AHTOXA @ Nov 9 2012, 22:33) *
Да вроде не особо, uint32_t выровняли на 4 байта. Не вижу криминалаsm.gif

Разобрался... чего-то вбил себе в голову, что uint16_t там не подряд идут. И непонятно, чего там так, там эдак. Тогда всё правильно.

Сообщение отредактировал _Pasha - Nov 9 2012, 19:44
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 20 2013, 09:45
Сообщение #70


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Всплыл вопрос, кажется, подойдет в эту тему.
Создаю суперструктуру из нескольких разных структур. В каждой из структур переменные разного размера кидаю, как попало. Не знаю, создаются дыры или нет, но пока использовал структуры по-отдельности, проблем не было. Keil знает, куда положил, и откуда брать. Для Cortex-M нет проблем. В суперструктуре должно быть аналогично.

Теперь хочу копировать суперструктуру в другую, такую же (backup). Хочу делать это 32-битовыми пересылками. Кроме того, хочу вычислять аппаратно CRC суперструктуры, туда тоже нужно посылать 32-битовые слова.
Задаю указателю на uint32 адрес суперструктуры (uint32_t *)&Ctrl. Вычисляю ее размер в словах (!) size(Ctrl_t) / 4. И так собираюсь использовать.

Вопросы:
1. Что гарантирует, что вся суперструктура разместится по выровненному до слова адресу? Что будет, если первый элемент - 8-битовый?
2. Как задать, чтобы ее размер был равен целому числу слов? Пока напихал несколько пустых байтов, каждая мелкая структура - по 2-4-8 байтов, общее количество 44 байта (но, может, есть и дыры двухбайтовые?). В конце суперструктуры задаю 32-битовую CRC, это гарантирует выравнивание по словам, и целое число слов?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Dec 20 2013, 10:35
Сообщение #71


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ViKo @ Dec 20 2013, 13:45) *
1. Что гарантирует, что вся суперструктура разместится по выровненному до слова адресу? Что будет, если первый элемент - 8-битовый?

Если явно определено выравнивание (pack или aligned), то вроде как должно.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 20 2013, 10:44
Сообщение #72


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Почитал здесь - http://www.keil.com/support/man/docs/armcc...he.htm#Cihbbgii
Похоже, ничего делать не надо.

Цитата(MrYuran @ Dec 20 2013, 13:35) *
Если явно определено выравнивание (pack или aligned), то вроде как должно.

Похоже, лучше, наоборот, ничего не задавать. Тогда само разместится ровненько.
Go to the top of the page
 
+Quote Post
ig_z
сообщение Dec 20 2013, 11:05
Сообщение #73


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551



QUOTE (ViKo @ Dec 20 2013, 11:45) *
2. Как задать, чтобы ее размер был равен целому числу слов?


Я точно не вспомню, но делал что то типа такого:
Помещал "супер структуру" + массив байт в "супер-супер структуру"
Размерность массива байт задавал как остаток от деления sizeof("супер структура") на 4.
Единственное, что не могу вспомнить, как обходил ситуацию с нулевым размером массива байт.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 20 2013, 11:08
Сообщение #74


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Запустил компиляцию с опцией --remarks.
Вижу:
enum занимают по 32 бита! Неоправданная роскошь.
К структуре с enum и 3-мя uint_16 добавилось... видимо 2 байта в конце.
По структуре Ctrl никаких замечаний не увидел.

Добавил uint8_t в конец Ctrl. Получил замечание, что добавило padding.
Делаю вывод - ничего не бойся, не проси... rolleyes.gif Сам Кейл придет и принесет.
Go to the top of the page
 
+Quote Post
PheeL
сообщение Dec 20 2013, 11:14
Сообщение #75


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 24-11-07
Пользователь №: 32 633



Цитата(ViKo @ Dec 20 2013, 15:08) *
enum занимают по 32 бита! Неоправданная роскошь.

Каждый из элементов enum - это int. Так что если машинное слово 32-х разрядное, то всё верно.


--------------------
Если друг оказался вдруг и не друг и не враг, а - JTAG.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 20 2013, 11:44
Сообщение #76


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(PheeL @ Dec 20 2013, 14:14) *
Каждый из элементов enum - это int. Так что если машинное слово 32-х разрядное, то всё верно.

Да, верно. Просто я об этом не задумывался. Да оно и нашлось всего в одном месте. Там и не сам enum стоял, а производный тип - typedef enum {...} ... Заменю на uint16_t и сэкономлю 4 байта!

Что любопытно. Имею в структуре 2 байта, в первом - битовые поля, во втором - uint8_t (вообще, reserv, для выше сказанного выравнивания). Так вот, такую 2-байтовую структуру Keil размещает в суперструктуре, не выравнивая по 2-байтовой границе. Как и написано по вышеприведенной ссылке, структура выравнивается по границе ее наибольшего члена.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 24 2013, 09:55
Сообщение #77


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(ViKo @ Dec 20 2013, 13:45) *
1. Что гарантирует, что вся суперструктура разместится по выровненному до слова адресу?
Компилятор гарантирует, что любое поле структуры (в том числе и поля вложенных структур) будет выровнено на его размер. Так же гарантируется, что это будет так и для массива структур. Отсюда автоматически следует, что сама структура всегда будет выровнена по ее полю с максимальным размером, и размер структуры тоже будет кратен размеру этого поля.
Цитата
Что будет, если первый элемент - 8-битовый?
Не важно, какой первый. Главное, что бы внутри был хотя бы один int
Цитата
В конце суперструктуры задаю 32-битовую CRC, это гарантирует выравнивание по словам, и целое число слов?
Да
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 24 2013, 16:06
Сообщение #78


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(ViKo @ Dec 20 2013, 11:45) *
В конце суперструктуры задаю 32-битовую CRC, это гарантирует выравнивание по словам, и целое число слов?
Как уже было сказано - да, гарантирует. Но все "дырки", оставшиеся от выравнивания полей, могут быть заполнены совершенно произвольным мусором. Учтите это при расчете CRC. Т.е. либо перед заполнением полей структуры обнуляйте выделенную под нее память при помощи memset, либо считайте CRC конкретных полей, а не всей памяти струткуры, либо размещайте поля так, чтобы не между ними не образовывалось "дырок".


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Dec 24 2013, 18:52
Сообщение #79


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Dec 24 2013, 22:06) *
Но все "дырки", оставшиеся от выравнивания полей, могут быть заполнены совершенно произвольным мусором. Учтите это при расчете CRC.

Да, как-то я напоролся на такое. Была структура, в конце структуры crc16. При инициализации проверялось crc, и, в случае несовпадения, значениям структуры присваивались значения по умолчанию.
Всё это прекрасно работало, до тех пор, пока я не поменял размер одного члена структуры с uint8_t на uint16_t. После этой замены моя программа стала дурить. Оказалось, что при смене размера члена общий размер структуры не изменился, crc16 тоже совпал. А вот значение этого члена получилось недопустимо большое (за счёт добавленного байта).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

6 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 05:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.02438 секунд с 7
ELECTRONIX ©2004-2016