Ivan. 4 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба Доброго времени суток! Предположим, что у нас есть упакованная структура данных: struct Foo { uint8_t v1; uint16_t v2; } __attribute__((packed)); Foo foo; Поле foo.v2 расположено по невыровненному адресу и при работе с данным полем компилятор автоматически выполняет побайтовое копирование (и это правильно). Теперь попробуем взять указатель на данное поле: uint16_t *vPtr = &foo.v2; Компилятор выдаст предупреждение: warning: taking address of packed member of 'Foo' may result in an unaligned pointer value (и это тоже правильно) А существует ли такой атрибут, позволяющий брать невыровненный указатель, чтобы компилятор понимал, что с ним тоже нужно работать как с невыровненным? что-то типа такого: uint16_t *vPtr __attribute__((packed)) = &foo.v2; *vPtr = 10; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 160 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба Компилятор какой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 215 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба 1 час назад, Ivan. сказал: А существует ли такой атрибут, позволяющий брать невыровненный указатель, чтобы компилятор понимал, что с ним тоже нужно работать как с невыровненным? У IAR существует: __packed Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба Gcc Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 215 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба 1 час назад, Ivan. сказал: Поле foo.v2 расположено по невыровненному адресу и при работе с данным полем компилятор автоматически выполняет побайтовое копирование (и это правильно). Не факт. Для ядер >= Cortex-M3 && <= Cortex-M7 это скорее неправильно. Правильно было бы использовать LDRH/STRH. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба По этому правильнее одеть это на усмотрение компилятора. Он то точно знает можно ли брать 2 бита по нечетному адресу или нет. 14 минут назад, jcxz сказал: Не факт. Для ядер >= Cortex-M3 && <= Cortex-M7 это скорее неправильно. Правильно было бы использовать LDRH/STRH. Это еще зависит от региона. Я столкнулся в M7, что в одном домене можно брать невыровненные данные, а в другом вылетает в hardfault Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 215 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба 1 час назад, Ivan. сказал: По этому правильнее одеть это на усмотрение компилятора. Он то точно знает можно ли брать 2 бита по нечетному адресу или нет. Какие биты? О чём речь? Компилятор знает, что Cortex-M умеет невыровненный доступ. Поэтому он использует LDR/STR/LDRH/STRH. 1 час назад, Ivan. сказал: Это еще зависит от региона. Я столкнулся в M7, что в одном домене можно брать невыровненные данные, а в другом вылетает в hardfault В каком "домене"? Какие данные (разрядность)? О чём речь? CM7 умеет невыровненный доступ (если его преднамеренно не запрещать). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба 9 минут назад, jcxz сказал: Какие биты? О чём речь? Байты конечно. опечатался 12 минут назад, jcxz сказал: В каком "домене"? Какие данные (разрядность)? О чём речь? Опять мы уходим в сторону. Вопрос не об этом Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 70 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба Как раз pakсed и упакует структуру без зазоров на выравнивание. Там ведь неравные переменные по ширине - 16 и 8, остается зазор, который будет устранен аттрибутом packed Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба Читайте вопрос внимательно. Как присвоить указатель на невыровненные данные, чтобы компилятор работал с этим указателем как с невыровненным Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 160 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба __unaligned uint16_t *ptr = &Foo.v2; Умеет GCC это ключевое слово? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arhiv6 15 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба В cmsis_gcc.h есть макрос __UNALIGNED_UINT32(x) : Цитата struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) Если я правильно понял, так сделано потому что в gcc атрибут __attribute__((packed)) можно применять только к структурам, а не к произвольным типам. Возможно, можно что-то подобное сделать для uint16_t ? В том же файле чуть ниже есть макросы __UNALIGNED_UINT16_READ и __UNALIGNED_UINT16_WRITE где подобным образом к данным обращаются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 160 18 октября, 2023 Опубликовано 18 октября, 2023 · Жалоба 7 минут назад, arhiv6 сказал: В cmsis_gcc.h есть макрос __UNALIGNED_UINT32(x) : Если я правильно понял, так сделано потому что в gcc атрибут __attribute__((packed)) можно применять только к структурам, а не к произвольным типам. Возможно, можно что-то подобно сделать для uint16_t ? В том же файле чуть ниже есть макросы __UNALIGNED_UINT16_READ и __UNALIGNED_UINT16_WRITE где подобным образом к данным обращаются. Похоже, это действительно решение в GCC, а на strict aliasing они решили забить... Мда Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 18 19 октября, 2023 Опубликовано 19 октября, 2023 · Жалоба Вообще нормальная практика предполагает все-таки выравнивание в структурах. Грубо говоря, сначала укладываем 32б данные (float, long etc), потом парами 16б, потом уже обнобайтные. Зачем создавать себе проблемы на ровном месте, чтобы потом их героически решать, закладывая при этом мины будущим поколениям разработчиков (или себе будущему) On 10/18/2023 at 8:52 PM, Ivan. said: Читайте вопрос внимательно. Как присвоить указатель на невыровненные данные, чтобы компилятор работал с этим указателем как с невыровненным привести к (uint8_t*), но это дурной стиль. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 160 19 октября, 2023 Опубликовано 19 октября, 2023 · Жалоба 36 минут назад, MrYuran сказал: Зачем создавать себе проблемы на ровном месте, чтобы потом их героически решать, закладывая при этом мины будущим поколениям разработчиков Вы щас серьезно?😆 А как быть с тем, что уже сделано предыдущим поколение разработчиков, причем, буквально повсюду? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться